diff --git a/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php b/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php
index cf52ebbe0669ae45c8ec130f440f557b22865427..a4d8b53934937cd2342f00bfd5505f6d59953ecc 100644
--- a/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php
+++ b/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php
@@ -16,12 +16,23 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt
      */
     protected $indexBuilder;
 
+    /**
+     * Application Event Dispatcher
+     *
+     * @var \Magento\Framework\Event\ManagerInterface
+     */
+    protected $_eventManager;
+
     /**
      * @param IndexBuilder $indexBuilder
+     * @param \Magento\Framework\Event\ManagerInterface $eventManager
      */
-    public function __construct(IndexBuilder $indexBuilder)
-    {
+    public function __construct(
+        IndexBuilder $indexBuilder,
+        \Magento\Framework\Event\ManagerInterface $eventManager
+    ) {
         $this->indexBuilder = $indexBuilder;
+        $this->_eventManager = $eventManager;
     }
 
     /**
@@ -43,6 +54,20 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt
     public function executeFull()
     {
         $this->indexBuilder->reindexFull();
+        $this->_eventManager->dispatch('clean_cache_by_tags', ['object' => $this]);
+    }
+
+    /**
+     * Get affected cache tags
+     *
+     * @return array
+     */
+    public function getIdentities()
+    {
+        return [
+            \Magento\Catalog\Model\Category::CACHE_TAG,
+            \Magento\Catalog\Model\Product::CACHE_TAG
+        ];
     }
 
     /**
diff --git a/app/code/Magento/CatalogRule/Model/Rule.php b/app/code/Magento/CatalogRule/Model/Rule.php
index 61eac7c2b59f204a98ee782994d04eed6e97bfbf..99eb4752f691cb88006c3cd108782aa53600e991 100644
--- a/app/code/Magento/CatalogRule/Model/Rule.php
+++ b/app/code/Magento/CatalogRule/Model/Rule.php
@@ -143,6 +143,11 @@ class Rule extends \Magento\Rule\Model\AbstractModel
      */
     protected $dateTime;
 
+    /**
+     * @var \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor;
+     */
+    protected $_ruleProductProcessor;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -158,6 +163,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel
      * @param \Magento\CatalogRule\Helper\Data $catalogRuleData
      * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
+     * @param \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor $ruleProductProcessor
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
      * @param array $relatedCacheTypes
@@ -179,6 +185,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel
         \Magento\CatalogRule\Helper\Data $catalogRuleData,
         \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList,
         \Magento\Framework\Stdlib\DateTime $dateTime,
+        \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor $ruleProductProcessor,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $relatedCacheTypes = [],
@@ -195,6 +202,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel
         $this->_cacheTypesList = $cacheTypesList;
         $this->_relatedCacheTypes = $relatedCacheTypes;
         $this->dateTime = $dateTime;
+        $this->_ruleProductProcessor = $ruleProductProcessor;
         parent::__construct($context, $registry, $formFactory, $localeDate, $resource, $resourceCollection, $data);
     }
 
@@ -445,4 +453,33 @@ class Rule extends \Magento\Rule\Model\AbstractModel
         }
         return $this;
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return $this
+     */
+    public function afterSave()
+    {
+        if ($this->isObjectNew()) {
+            $this->getMatchingProductIds();
+            if (!empty($this->_productIds) && is_array($this->_productIds)) {
+                $this->_ruleProductProcessor->reindexList($this->_productIds);
+            }
+        } else {
+            $this->_ruleProductProcessor->getIndexer()->invalidate();
+        }
+        return parent::afterSave();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return $this
+     */
+    public function afterDelete()
+    {
+        $this->_ruleProductProcessor->getIndexer()->invalidate();
+        return parent::afterDelete();
+    }
 }
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/AbstractIndexerTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/AbstractIndexerTest.php
index 526ea7786417882ee711161a4021d27b66fcf7e7..b9a21020e4120a7218a7af66fc9ba0d833a2ebc8 100644
--- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/AbstractIndexerTest.php
+++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/AbstractIndexerTest.php
@@ -18,16 +18,35 @@ class AbstractIndexerTest extends \PHPUnit_Framework_TestCase
      */
     protected $indexer;
 
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_eventManagerMock;
+
+    /**
+     * Set up test
+     *
+     * @return void
+     */
     protected function setUp()
     {
+        $this->_eventManagerMock = $this->getMock('\Magento\Framework\Event\ManagerInterface');
         $this->indexBuilder = $this->getMock('Magento\CatalogRule\Model\Indexer\IndexBuilder', [], [], '', false);
 
         $this->indexer = $this->getMockForAbstractClass(
             'Magento\CatalogRule\Model\Indexer\AbstractIndexer',
-            [$this->indexBuilder]
+            [
+                $this->indexBuilder,
+                $this->_eventManagerMock
+            ]
         );
     }
 
+    /**
+     * Test execute
+     *
+     * @return void
+     */
     public function testExecute()
     {
         $ids = [1, 2, 5];
@@ -36,9 +55,20 @@ class AbstractIndexerTest extends \PHPUnit_Framework_TestCase
         $this->indexer->execute($ids);
     }
 
+    /**
+     * Test execute full reindex action
+     *
+     * @return void
+     */
     public function testExecuteFull()
     {
         $this->indexBuilder->expects($this->once())->method('reindexFull');
+        $this->_eventManagerMock->expects($this->once())
+            ->method('dispatch')
+            ->with(
+                'clean_cache_by_tags',
+                ['object' => $this->indexer]
+            );
 
         $this->indexer->executeFull();
     }
@@ -46,12 +76,19 @@ class AbstractIndexerTest extends \PHPUnit_Framework_TestCase
     /**
      * @expectedException \Magento\CatalogRule\CatalogRuleException
      * @expectedExceptionMessage Could not rebuild index for empty products array
+     *
+     * @return void
      */
     public function testExecuteListWithEmptyIds()
     {
         $this->indexer->executeList([]);
     }
 
+    /**
+     * @throws \Magento\CatalogRule\CatalogRuleException
+     *
+     * @return void
+     */
     public function testExecuteList()
     {
         $ids = [1, 2, 5];
@@ -63,12 +100,19 @@ class AbstractIndexerTest extends \PHPUnit_Framework_TestCase
     /**
      * @expectedException \Magento\CatalogRule\CatalogRuleException
      * @expectedExceptionMessage Could not rebuild index for undefined product
+     *
+     * @return void
      */
     public function testExecuteRowWithEmptyId()
     {
         $this->indexer->executeRow(null);
     }
 
+    /**
+     * @throws \Magento\CatalogRule\CatalogRuleException
+     *
+     * @return void
+     */
     public function testExecuteRow()
     {
         $id = 5;
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/RuleTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/RuleTest.php
index 095ca9891a7405407df9b759950721b4d2676d40..4b3d8d2edd1875f00b0244b31f82a2796e6bc60e 100644
--- a/app/code/Magento/CatalogRule/Test/Unit/Model/RuleTest.php
+++ b/app/code/Magento/CatalogRule/Test/Unit/Model/RuleTest.php
@@ -31,6 +31,31 @@ class RuleTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Rule\Model\Condition\Combine|\PHPUnit_Framework_MockObject_MockObject */
     protected $condition;
 
+    /**
+     * @var \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_ruleProductProcessor;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_productCollectionFactory;
+
+    /**
+     * @var \Magento\Framework\Model\Resource\Iterator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_resourceIterator;
+
+    /**
+     * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productModel;
+
+    /**
+     * Set up before test
+     *
+     * @return void
+     */
     protected function setUp()
     {
         $this->storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface');
@@ -74,13 +99,39 @@ class RuleTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->_ruleProductProcessor = $this->getMock(
+            '\Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->_productCollectionFactory = $this->getMock(
+            '\Magento\Catalog\Model\Resource\Product\CollectionFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+
+        $this->_resourceIterator = $this->getMock(
+            '\Magento\Framework\Model\Resource\Iterator',
+            ['walk'],
+            [],
+            '',
+            false
+        );
 
         $this->objectManagerHelper = new ObjectManagerHelper($this);
         $this->rule = $this->objectManagerHelper->getObject(
             'Magento\CatalogRule\Model\Rule',
             [
                 'storeManager' => $this->storeManager,
-                'combineFactory' => $this->combineFactory
+                'combineFactory' => $this->combineFactory,
+                'ruleProductProcessor' => $this->_ruleProductProcessor,
+                'productCollectionFactory' => $this->_productCollectionFactory,
+                'resourceIterator' => $this->_resourceIterator,
             ]
         );
     }
@@ -88,6 +139,8 @@ class RuleTest extends \PHPUnit_Framework_TestCase
     /**
      * @dataProvider dataProviderCallbackValidateProduct
      * @param bool $validate
+     *
+     * @return void
      */
     public function testCallbackValidateProduct($validate)
     {
@@ -134,6 +187,11 @@ class RuleTest extends \PHPUnit_Framework_TestCase
         }
     }
 
+    /**
+     * Data provider for callbackValidateProduct test
+     *
+     * @return array
+     */
     public function dataProviderCallbackValidateProduct()
     {
         return [
@@ -141,4 +199,31 @@ class RuleTest extends \PHPUnit_Framework_TestCase
             [true],
         ];
     }
+
+    /**
+     * Test after delete action
+     *
+     * @return void
+     */
+    public function testAfterDelete()
+    {
+        $indexer = $this->getMock('\Magento\Indexer\Model\IndexerInterface');
+        $indexer->expects($this->once())->method('invalidate');
+        $this->_ruleProductProcessor->expects($this->once())->method('getIndexer')->will($this->returnValue($indexer));
+        $this->rule->afterDelete();
+    }
+
+    /**
+     * Test after update action
+     *
+     * @return void
+     */
+    public function testAfterUpdate()
+    {
+        $this->rule->isObjectNew(false);
+        $indexer = $this->getMock('\Magento\Indexer\Model\IndexerInterface');
+        $indexer->expects($this->once())->method('invalidate');
+        $this->_ruleProductProcessor->expects($this->once())->method('getIndexer')->will($this->returnValue($indexer));
+        $this->rule->afterSave();
+    }
 }