diff --git a/app/code/Magento/CacheInvalidate/Model/Observer.php b/app/code/Magento/CacheInvalidate/Model/Observer.php
new file mode 100644
index 0000000000000000000000000000000000000000..6deb4f50aac511b57fc7bf5cf920a6f172bad351
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/Model/Observer.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CacheInvalidate\Model;
+
+/**
+ * Class Observer
+ */
+class Observer
+{
+    /**
+     * Application config object
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $_config;
+
+    /**
+     * @var \Magento\PageCache\Helper\Data
+     */
+    protected $_helper;
+
+    /**
+     * @var \Magento\Framework\HTTP\Adapter\Curl
+     */
+    protected $_curlAdapter;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\PageCache\Model\Config $config
+     * @param \Magento\PageCache\Helper\Data $helper
+     * @param \Magento\Framework\HTTP\Adapter\Curl $curlAdapter
+     */
+    public function __construct(
+        \Magento\PageCache\Model\Config $config,
+        \Magento\PageCache\Helper\Data $helper,
+        \Magento\Framework\HTTP\Adapter\Curl $curlAdapter
+    ) {
+        $this->_config = $config;
+        $this->_helper = $helper;
+        $this->_curlAdapter = $curlAdapter;
+    }
+
+    /**
+     * If Varnish caching is enabled it collects array of tags
+     * of incoming object and asks to clean cache.
+     *
+     * @param \Magento\Framework\Event\Observer $observer
+     * @return void
+     */
+    public function invalidateVarnish(\Magento\Framework\Event\Observer $observer)
+    {
+        if ($this->_config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->_config->isEnabled()) {
+            $object = $observer->getEvent()->getObject();
+            if ($object instanceof \Magento\Framework\Object\IdentityInterface) {
+                $tags = [];
+                $pattern = "((^|,)%s(,|$))";
+                foreach ($object->getIdentities() as $tag) {
+                    $tags[] = sprintf($pattern, preg_replace("~_\\d+$~", '', $tag));
+                    $tags[] = sprintf($pattern, $tag);
+                }
+                $this->sendPurgeRequest(implode('|', array_unique($tags)));
+            }
+        }
+    }
+
+    /**
+     * Flash Varnish cache
+     *
+     * @param \Magento\Framework\Event\Observer $observer
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function flushAllCache(\Magento\Framework\Event\Observer $observer)
+    {
+        if ($this->_config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->_config->isEnabled()) {
+            $this->sendPurgeRequest('.*');
+        }
+    }
+
+    /**
+     * Send curl purge request
+     * to invalidate cache by tags pattern
+     *
+     * @param string $tagsPattern
+     * @return void
+     */
+    protected function sendPurgeRequest($tagsPattern)
+    {
+        $headers = ["X-Magento-Tags-Pattern: {$tagsPattern}"];
+        $this->_curlAdapter->setOptions([CURLOPT_CUSTOMREQUEST => 'PURGE']);
+        $this->_curlAdapter->write('', $this->_helper->getUrl('*'), '1.1', $headers);
+        $this->_curlAdapter->read();
+        $this->_curlAdapter->close();
+    }
+}
diff --git a/app/code/Magento/CacheInvalidate/README.md b/app/code/Magento/CacheInvalidate/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6cca6ffec03e45b5b7c09ba7d6e8a6543e14eb00
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/README.md
@@ -0,0 +1,2 @@
+The CacheInvalidate module is used to invalidate the Varnish cache if it is configured.
+It listens for events that request the cache to be flushed or cause the cache to be invalid, then sends Varnish a purge request using cURL.
\ No newline at end of file
diff --git a/app/code/Magento/CacheInvalidate/Test/Unit/Model/ObserverTest.php b/app/code/Magento/CacheInvalidate/Test/Unit/Model/ObserverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1abf5d45605acb48f111f7126ab58dcae9c9e540
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/Test/Unit/Model/ObserverTest.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CacheInvalidate\Test\Unit\Model;
+
+class ObserverTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\CacheInvalidate\Model\Observer */
+    protected $_model;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Event\Observer */
+    protected $_observerMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\HTTP\Adapter\Curl */
+    protected $_curlMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\PageCache\Model\Config */
+    protected $_configMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\PageCache\Helper\Data */
+    protected $_helperMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Object\ */
+    protected $_observerObject;
+
+    /**
+     * Set up all mocks and data for test
+     */
+    public function setUp()
+    {
+        $this->_configMock = $this->getMock(
+            'Magento\PageCache\Model\Config',
+            ['getType', 'isEnabled'],
+            [],
+            '',
+            false
+        );
+        $this->_helperMock = $this->getMock('Magento\PageCache\Helper\Data', ['getUrl'], [], '', false);
+        $this->_curlMock = $this->getMock(
+            '\Magento\Framework\HTTP\Adapter\Curl',
+            ['setOptions', 'write', 'read', 'close'],
+            [],
+            '',
+            false
+        );
+        $this->_model = new \Magento\CacheInvalidate\Model\Observer(
+            $this->_configMock,
+            $this->_helperMock,
+            $this->_curlMock
+        );
+        $this->_observerMock = $this->getMock(
+            'Magento\Framework\Event\Observer',
+            ['getEvent'],
+            [],
+            '',
+            false
+        );
+        $this->_observerObject = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+    }
+
+    /**
+     * Test case for cache invalidation
+     */
+    public function testInvalidateVarnish()
+    {
+        $tags = ['cache_1', 'cache_group'];
+        $pattern = '((^|,)cache(,|$))|((^|,)cache_1(,|$))|((^|,)cache_group(,|$))';
+
+        $this->_configMock->expects($this->once())->method('isEnabled')->will($this->returnValue(true));
+        $this->_configMock->expects(
+            $this->once()
+        )->method(
+            'getType'
+        )->will(
+            $this->returnValue(\Magento\PageCache\Model\Config::VARNISH)
+        );
+        $eventMock = $this->getMock('Magento\Framework\Event', ['getObject'], [], '', false);
+        $eventMock->expects($this->once())->method('getObject')->will($this->returnValue($this->_observerObject));
+        $this->_observerMock->expects($this->once())->method('getEvent')->will($this->returnValue($eventMock));
+        $this->_observerObject->expects($this->once())->method('getIdentities')->will($this->returnValue($tags));
+        $this->sendPurgeRequest($pattern);
+
+        $this->_model->invalidateVarnish($this->_observerMock);
+    }
+
+    /**
+     * Test case for flushing all the cache
+     */
+    public function testFlushAllCache()
+    {
+        $this->_configMock->expects($this->once())->method('isEnabled')->will($this->returnValue(true));
+        $this->_configMock->expects(
+            $this->once()
+        )->method(
+            'getType'
+        )->will(
+            $this->returnValue(\Magento\PageCache\Model\Config::VARNISH)
+        );
+
+        $this->sendPurgeRequest('.*');
+        $this->_model->flushAllCache($this->_observerMock);
+    }
+
+    /**
+     * @param string $tags
+     */
+    protected function sendPurgeRequest($tags)
+    {
+        $url = 'http://mangento.index.php';
+        $httpVersion = '1.1';
+        $headers = ["X-Magento-Tags-Pattern: {$tags}"];
+        $this->_helperMock->expects(
+            $this->any()
+        )->method(
+            'getUrl'
+        )->with(
+            $this->equalTo('*'),
+            []
+        )->will(
+            $this->returnValue($url)
+        );
+        $this->_curlMock->expects($this->once())->method('setOptions')->with([CURLOPT_CUSTOMREQUEST => 'PURGE']);
+        $this->_curlMock->expects(
+            $this->once()
+        )->method(
+            'write'
+        )->with(
+            $this->equalTo(''),
+            $this->equalTo($url),
+            $httpVersion,
+            $this->equalTo($headers)
+        );
+        $this->_curlMock->expects($this->once())->method('read');
+        $this->_curlMock->expects($this->once())->method('close');
+    }
+}
diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..3fe142a52e825fe6bae3ab6d56e798302d3ba3c3
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/composer.json
@@ -0,0 +1,24 @@
+{
+    "name": "magento/module-cache-invalidate",
+    "description": "N/A",
+    "require": {
+        "php": "~5.5.0|~5.6.0",
+        "magento/module-page-cache": "0.74.0-beta4",
+        "magento/framework": "0.74.0-beta4",
+        "magento/magento-composer-installer": "*"
+    },
+    "type": "magento2-module",
+    "version": "0.74.0-beta4",
+    "license": [
+        "OSL-3.0",
+        "AFL-3.0"
+    ],
+    "extra": {
+        "map": [
+            [
+                "*",
+                "Magento/CacheInvalidate"
+            ]
+        ]
+    }
+}
diff --git a/app/code/Magento/CacheInvalidate/etc/events.xml b/app/code/Magento/CacheInvalidate/etc/events.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4ba3665ee66fb4e1e1eee75045302c199bf2985
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/etc/events.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
+    <event name="clean_cache_by_tags">
+        <observer name="invalidate_varnish" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="adminhtml_cache_flush_system">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="clean_media_cache_after">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="clean_catalog_images_cache_after">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="assigned_theme_changed">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="catalogrule_after_apply">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="adminhtml_cache_refresh_type">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="adminhtml_cache_flush_all">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="assign_theme_to_stores_after">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_system_currency_saveRates">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_system_config_save">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_catalog_product_action_attribute_save">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_catalog_product_massStatus">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_system_currencysymbol_save">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+</config>
diff --git a/app/code/Magento/CacheInvalidate/etc/module.xml b/app/code/Magento/CacheInvalidate/etc/module.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ca87df877a43a93eb2be450fa10b0013d099eff9
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/etc/module.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_CacheInvalidate" setup_version="2.0.0">
+        <sequence>
+            <module name="Magento_Store"/>
+        </sequence>
+    </module>
+</config>
diff --git a/composer.json b/composer.json
index c8721c87609c6a84b5b35d2abd2e15b2f0fddbdb..907d23ff711529e697064e42d0eab2a6c2465669 100644
--- a/composer.json
+++ b/composer.json
@@ -63,6 +63,7 @@
         "magento/module-backend": "self.version",
         "magento/module-backup": "self.version",
         "magento/module-bundle": "self.version",
+        "magento/module-cache-invalidate": "self.version",
         "magento/module-captcha": "self.version",
         "magento/module-catalog": "self.version",
         "magento/module-catalog-import-export": "self.version",
diff --git a/composer.lock b/composer.lock
index 02e531e791e517c23da1202be3be61491553ec1d..1850375542413cf443c72fd68f36fd6fe6b21d7f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "974fa7d59a25f8a31c70ea53068944cd",
+    "hash": "35d05640e3dc260b7a5b09310611194a",
     "packages": [
         {
             "name": "composer/composer",
@@ -2007,16 +2007,16 @@
         },
         {
             "name": "fabpot/php-cs-fixer",
-            "version": "v1.6.1",
+            "version": "v1.6.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
-                "reference": "14f802b2c00b672676d55612e3c0d03465b69bf6"
+                "reference": "a574ba148953fea1f78428d4b7c6843e759711f3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/14f802b2c00b672676d55612e3c0d03465b69bf6",
-                "reference": "14f802b2c00b672676d55612e3c0d03465b69bf6",
+                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/a574ba148953fea1f78428d4b7c6843e759711f3",
+                "reference": "a574ba148953fea1f78428d4b7c6843e759711f3",
                 "shasum": ""
             },
             "require": {
@@ -2056,7 +2056,7 @@
                 }
             ],
             "description": "A script to automatically fix Symfony Coding Standard",
-            "time": "2015-04-09 19:10:26"
+            "time": "2015-04-13 21:33:33"
         },
         {
             "name": "league/climate",
@@ -2272,16 +2272,16 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "2.0.15",
+            "version": "2.0.16",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "34cc484af1ca149188d0d9e91412191e398e0b67"
+                "reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67",
-                "reference": "34cc484af1ca149188d0d9e91412191e398e0b67",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/934fd03eb6840508231a7f73eb8940cf32c3b66c",
+                "reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c",
                 "shasum": ""
             },
             "require": {
@@ -2330,7 +2330,7 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2015-01-24 10:06:35"
+            "time": "2015-04-11 04:35:00"
         },
         {
             "name": "phpunit/php-file-iterator",