diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java
index 3bad6a0..d098292 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java
@@ -119,4 +119,10 @@ public interface IndexConstants {
      */
     String INDEX_NAME_OPTION = ":indexName";
 
+    /**
+     * Boolean property on any index node indicating that such a node should not be
+     * removed during reindex
+     */
+    String REINDEX_RETAIN = "retainNodeInReindex";
+
 }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
index 6805fe5..11cbc99 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
@@ -234,6 +234,10 @@ public class IndexUpdate implements Editor, PathSource {
     private static boolean hasAnyHiddenNodes(NodeBuilder builder){
         for (String name : builder.getChildNodeNames()) {
             if (NodeStateUtils.isHidden(name)){
+                NodeBuilder childNode = builder.getChildNode(name);
+                if (childNode.getBoolean(IndexConstants.REINDEX_RETAIN)) {
+                    continue;
+                }
                 return true;
             }
         }
@@ -272,13 +276,7 @@ public class IndexUpdate implements Editor, PathSource {
                     } else {
                         definition.setProperty(REINDEX_PROPERTY_NAME, false);
                         incrementReIndexCount(definition);
-                        // as we don't know the index content node name
-                        // beforehand, we'll remove all child nodes
-                        for (String rm : definition.getChildNodeNames()) {
-                            if (NodeStateUtils.isHidden(rm)) {
-                                definition.getChildNode(rm).remove();
-                            }
-                        }
+                        removeIndexState(definition);
 
                         clearCorruptFlag(definition, indexPath);
                         reindex.put(concat(getPath(), INDEX_DEFINITIONS_NAME, name), editor);
@@ -290,6 +288,19 @@ public class IndexUpdate implements Editor, PathSource {
         }
     }
 
+    private void removeIndexState(NodeBuilder definition) {
+        // as we don't know the index content node name
+        // beforehand, we'll remove all child nodes
+        for (String rm : definition.getChildNodeNames()) {
+            if (NodeStateUtils.isHidden(rm)) {
+                NodeBuilder childNode = definition.getChildNode(rm);
+                if (!childNode.getBoolean(IndexConstants.REINDEX_RETAIN)) {
+                    definition.getChildNode(rm).remove();
+                }
+            }
+        }
+    }
+
     private long getEstimatedCount(NodeBuilder indexDefinition) {
         //TODO Implement the estimate
         return -1;
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
index 347891e..ff835d3 100644
--- oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
@@ -25,6 +25,7 @@ import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEXING_MO
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_ASYNC_PROPERTY_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_COUNT;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
 import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
@@ -336,6 +337,59 @@ public class IndexUpdateTest {
 
     }
 
+    /**
+     * Tests that with explicit reindex i.e. reindex=true those hidden nodes
+     * which have IndexConstants.REINDEX_RETAIN set to true are not removed
+     */
+    @Test
+    public void reindexSkipRemovalOfRetainedNodes() throws Exception{
+        builder.child("testRoot").setProperty("foo", "abc");
+        NodeState before = builder.getNodeState();
+
+        NodeBuilder nb = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+                "rootIndex", true, false, ImmutableSet.of("foo"), null);
+        nb.child(":hidden-node-1").setProperty("foo", "bar");
+        nb.child(":hidden-node-2").setProperty(IndexConstants.REINDEX_RETAIN, true);
+        nb.child("visible-node");
+
+        NodeState after = builder.getNodeState();
+
+        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+
+        // first check that the index content nodes exist
+        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME, "rootIndex");
+        checkPathExists(ns, "visible-node");
+        checkPathExists(ns, ":hidden-node-2");
+        assertFalse(ns.getChildNode(":hidden-node-1").exists());
+        assertEquals(1, ns.getLong(REINDEX_COUNT));
+    }
+
+    /**
+     * Test that an index is still reindexed if it has hidden nodes but with all such
+     * hidden nodes having IndexConstants.REINDEX_RETAIN set to true i.e. this index
+     * does not yet have any hidden nodes corresponding to persisted index like lucene
+     */
+    @Test
+    public void reindexSkipRemovalOfRetainedNodes_FreshIndex() throws Exception{
+        builder.child("testRoot").setProperty("foo", "abc");
+        NodeState before = builder.getNodeState();
+
+        NodeBuilder nb = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+                "rootIndex", false, false, ImmutableSet.of("foo"), null);
+        nb.child(":hidden-node-2").setProperty(IndexConstants.REINDEX_RETAIN, true);
+        nb.child("visible-node");
+
+        NodeState after = builder.getNodeState();
+
+        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+
+        // first check that the index content nodes exist
+        NodeState ns = checkPathExists(indexed, INDEX_DEFINITIONS_NAME, "rootIndex");
+        checkPathExists(ns, "visible-node");
+        checkPathExists(ns, ":hidden-node-2");
+        assertEquals(1, ns.getLong(REINDEX_COUNT));
+    }
+
 
     /**
      * Async Reindex Test (OAK-2174)
diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexUpdateCallback.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexUpdateCallback.java
index c21a1fd..1e631d7 100644
--- oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexUpdateCallback.java
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexUpdateCallback.java
@@ -27,6 +27,7 @@ import javax.jcr.PropertyType;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
 import org.apache.jackrabbit.oak.plugins.index.lucene.PropertyDefinition;
 import org.apache.jackrabbit.oak.plugins.index.lucene.PropertyUpdateCallback;
 import org.apache.jackrabbit.oak.plugins.index.property.ValuePattern;
@@ -129,6 +130,10 @@ public class PropertyIndexUpdateCallback implements PropertyUpdateCallback {
     private NodeBuilder getIndexNode(String propertyRelativePath, boolean unique) {
         NodeBuilder propertyIndex = builder.child(PROPERTY_INDEX);
 
+        if (propertyIndex.isNew()) {
+            propertyIndex.setProperty(IndexConstants.REINDEX_RETAIN, true);
+        }
+
         String nodeName = HybridPropertyIndexUtil.getNodeName(propertyRelativePath);
         if (unique) {
             return getUniqueIndexBuilder(propertyIndex, nodeName);
diff --git oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/SynchronousPropertyIndexTest.java oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/SynchronousPropertyIndexTest.java
index 74ef743..69098a8 100644
--- oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/SynchronousPropertyIndexTest.java
+++ oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/SynchronousPropertyIndexTest.java
@@ -326,7 +326,6 @@ public class SynchronousPropertyIndexTest extends AbstractQueryTest {
 
     }
 
-    @Ignore("OAK-6781")
     @Test
     public void asyncIndexerReindexAndPropertyIndexes() throws Exception{
         defnb.async("async", "nrt");
