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 d098292..8b653e1 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
@@ -125,4 +125,19 @@ public interface IndexConstants {
      */
     String REINDEX_RETAIN = "retainNodeInReindex";
 
+    /**
+     * Index type for disabled indexes
+     */
+    String TYPE_DISABLED = "disabled";
+
+    /**
+     * Multi value property referring to index paths which current index supersedes
+     */
+    String SUPERSEDED_INDEX_PATHS = "supersedes";
+
+    /**
+     * Boolean flag indicating that old indexes have been disabled
+     */
+    String DISABLED_OLD_INDEXES = "disabledOlderIndexes";
+
 }
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 11cbc99..4aa4ee9 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
@@ -56,6 +56,7 @@ import org.apache.jackrabbit.oak.plugins.index.NodeTraversalCallback.PathSource;
 import org.apache.jackrabbit.oak.plugins.index.progress.IndexingProgressReporter;
 import org.apache.jackrabbit.oak.plugins.index.progress.NodeCountEstimator;
 import org.apache.jackrabbit.oak.plugins.index.progress.TraversalRateEstimator;
+import org.apache.jackrabbit.oak.plugins.index.upgrade.IndexDisabler;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.Editor;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
@@ -143,7 +144,7 @@ public class IndexUpdate implements Editor, PathSource {
         this.parent = null;
         this.name = null;
         this.path = "/";
-        this.rootState = new IndexUpdateRootState(provider, async, root, updateCallback, traversalCallback, commitInfo, corruptIndexHandler);
+        this.rootState = new IndexUpdateRootState(provider, async, root, builder, updateCallback, traversalCallback, commitInfo, corruptIndexHandler);
         this.builder = checkNotNull(builder);
     }
 
@@ -282,6 +283,7 @@ public class IndexUpdate implements Editor, PathSource {
                         reindex.put(concat(getPath(), INDEX_DEFINITIONS_NAME, name), editor);
                     }
                 } else {
+                    rootState.indexDisabler.disableOldIndexes(indexPath, definition);
                     editors.add(editor);
                 }
             }
@@ -529,6 +531,7 @@ public class IndexUpdate implements Editor, PathSource {
         final String async;
         final NodeState root;
         final CommitInfo commitInfo;
+        final IndexDisabler indexDisabler;
         private boolean ignoreReindexFlags = IGNORE_REINDEX_FLAGS;
         final Set<IndexCommitCallback> indexCommitCallbacks = newIdentityHashSet();
         final CorruptIndexHandler corruptIndexHandler;
@@ -538,13 +541,15 @@ public class IndexUpdate implements Editor, PathSource {
         private MissingIndexProviderStrategy missingProvider = new MissingIndexProviderStrategy();
 
         private IndexUpdateRootState(IndexEditorProvider provider, String async, NodeState root,
-                                     IndexUpdateCallback updateCallback, NodeTraversalCallback traversalCallback,
+                                     NodeBuilder builder, IndexUpdateCallback updateCallback,
+                                     NodeTraversalCallback traversalCallback,
                                      CommitInfo commitInfo, CorruptIndexHandler corruptIndexHandler) {
             this.provider = checkNotNull(provider);
             this.async = async;
             this.root = checkNotNull(root);
             this.commitInfo = commitInfo;
             this.corruptIndexHandler = corruptIndexHandler;
+            this.indexDisabler = new IndexDisabler(builder);
             this.progressReporter = new IndexingProgressReporter(updateCallback, traversalCallback);
         }
 
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/upgrade/IndexDisabler.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/upgrade/IndexDisabler.java
new file mode 100644
index 0000000..13e381b
--- /dev/null
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/upgrade/IndexDisabler.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.plugins.index.upgrade;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Collections.emptyList;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DISABLED_OLD_INDEXES;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.SUPERSEDED_INDEX_PATHS;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_DISABLED;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+
+public class IndexDisabler {
+    private static final Logger log = LoggerFactory.getLogger(IndexDisabler.class);
+    private final NodeBuilder rootBuilder;
+
+    public IndexDisabler(NodeBuilder rootBuilder) {
+        this.rootBuilder = rootBuilder;
+    }
+
+    public List<String> disableOldIndexes(String currentIndexPath, NodeBuilder idxBuilder) {
+        PropertyState indexPathsProp = idxBuilder.getProperty(SUPERSEDED_INDEX_PATHS);
+
+        if (indexPathsProp == null) {
+            return emptyList();
+        }
+
+        if (idxBuilder.getBoolean(DISABLED_OLD_INDEXES)) {
+            return emptyList();
+        }
+
+        //Skip disabling for the cycle where reindexing just got completed
+        if (idxBuilder.isReplaced(REINDEX_PROPERTY_NAME)){
+            return emptyList();
+        }
+
+        Iterable<String> indexPaths = indexPathsProp.getValue(Type.STRINGS);
+        List<String> disabledIndexes = new ArrayList<>();
+        for (final String indexPath : indexPaths) {
+            if (isNodeTypePath(indexPath)) {
+                String nodeTypeName = PathUtils.getName(indexPath).substring(1);
+                String nodeTypeIndexPath = PathUtils.getParentPath(indexPath);
+
+                NodeBuilder nodeTypeIndexBuilder = child(rootBuilder, nodeTypeIndexPath);
+                if (nodeTypeIndexBuilder.exists()
+                        && nodeTypeIndexBuilder.hasProperty(DECLARING_NODE_TYPES)){
+                    Set<String> existingTypes = Sets.newHashSet(nodeTypeIndexBuilder.
+                            getProperty(DECLARING_NODE_TYPES).getValue(Type.NAMES));
+                    if (existingTypes.remove(nodeTypeName)) {
+                        disabledIndexes.add(indexPath);
+                        nodeTypeIndexBuilder.setProperty(DECLARING_NODE_TYPES, existingTypes, Type.NAMES);
+                    }
+                }
+            } else {
+                NodeBuilder disabledIndexBuilder = child(rootBuilder, indexPath);
+                if (disabledIndexBuilder.exists()) {
+                    disabledIndexBuilder.setProperty(TYPE_PROPERTY_NAME, TYPE_DISABLED);
+                    disabledIndexes.add(indexPath);
+                }
+            }
+        }
+
+        if (!disabledIndexes.isEmpty()) {
+            log.info("Index at [{}] supersedes indexes {}. Marking those as disabled",
+                    currentIndexPath, disabledIndexes);
+            idxBuilder.setProperty(DISABLED_OLD_INDEXES, true);
+        }
+
+        return disabledIndexes;
+    }
+
+    private static boolean isNodeTypePath(String indexPath) {
+        String lastPathSegment = PathUtils.getName(indexPath);
+        return lastPathSegment.startsWith("@");
+    }
+
+    private static NodeBuilder child(NodeBuilder nb, String path) {
+        for (String name : PathUtils.elements(checkNotNull(path))) {
+            nb = nb.getChildNode(name);
+        }
+        return nb;
+    }
+}
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 ff835d3..880924f 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
@@ -27,6 +27,7 @@ import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFIN
 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.IndexConstants.TYPE_PROPERTY_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
 import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
 import static org.hamcrest.CoreMatchers.instanceOf;
@@ -875,6 +876,42 @@ public class IndexUpdateTest {
         }
     }
 
+    @Test
+    public void indexesDisabled() throws Exception{
+        NodeState before = builder.getNodeState();
+        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+                "fooIndex", true, false, ImmutableSet.of("foo"), null);
+        createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+                "barIndex", true, false, ImmutableSet.of("bar"), null);
+        builder.child("testRoot").setProperty("foo", "abc");
+        NodeState after = builder.getNodeState();
+
+        NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+
+        before = indexed;
+        builder = indexed.builder();
+        NodeBuilder newIndex = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+                "newIndex", true, false, ImmutableSet.of("bar"), null);
+        newIndex.setProperty(IndexConstants.SUPERSEDED_INDEX_PATHS, asList("/oak:index/fooIndex"), Type.STRINGS);
+
+        after = builder.getNodeState();
+        indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+
+        //Post reindex also index should not be disabled
+        assertEquals("property", indexed.getChildNode("oak:index").getChildNode("fooIndex").getString(TYPE_PROPERTY_NAME));
+
+        before = indexed;
+        builder = indexed.builder();
+        builder.child("testRoot2").setProperty("foo", "abc");
+        after = builder.getNodeState();
+        indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+
+        //Index only disabled after next cycle
+        assertEquals(IndexConstants.TYPE_DISABLED, indexed.getChildNode("oak:index").getChildNode("fooIndex").getString(TYPE_PROPERTY_NAME));
+        assertTrue(indexed.getChildNode("oak:index").getChildNode("newIndex").getBoolean(IndexConstants.DISABLED_OLD_INDEXES));
+
+    }
+
     private static void markCorrupt(NodeBuilder builder, String indexName) {
         builder.getChildNode(INDEX_DEFINITIONS_NAME).getChildNode(indexName)
                 .setProperty(IndexConstants.CORRUPT_PROPERTY_NAME, ISO8601.format(Calendar.getInstance()));
diff --git oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/upgrade/IndexDisablerTest.java oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/upgrade/IndexDisablerTest.java
new file mode 100644
index 0000000..b4f3a6f
--- /dev/null
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/upgrade/IndexDisablerTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.plugins.index.upgrade;
+
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_DISABLED;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
+import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.junit.Assert.*;
+
+public class IndexDisablerTest {
+    private NodeBuilder builder = EMPTY_NODE.builder();
+    private NodeBuilder rootBuilder = EMPTY_NODE.builder();
+    private IndexDisabler disabler = new IndexDisabler(rootBuilder);
+
+    @Test
+    public void simpleIndex() throws Exception{
+        List<String> disabledIndexes = disabler.disableOldIndexes("/oak:index/foo", builder);
+        assertTrue(disabledIndexes.isEmpty());
+    }
+
+    @Test
+    public void disableIndexes() throws Exception{
+        rootBuilder.child("oak:index").child("fooIndex");
+
+        builder.setProperty(IndexConstants.SUPERSEDED_INDEX_PATHS,
+                asList("/oak:index/fooIndex", "/oak:index/barIndex"), Type.STRINGS);
+
+        List<String> disabledIndexes = disabler.disableOldIndexes("/oak:index/foo", builder);
+        assertThat(disabledIndexes, containsInAnyOrder("/oak:index/fooIndex"));
+        assertTrue(builder.getBoolean(IndexConstants.DISABLED_OLD_INDEXES));
+        assertEquals(TYPE_DISABLED,
+                rootBuilder.getChildNode("oak:index").getChildNode("fooIndex").getString(TYPE_PROPERTY_NAME));
+
+        //Check no node created for non existing node
+        assertFalse(rootBuilder.getChildNode("oak:index").getChildNode("barIndex").exists());
+
+        builder = builder.getNodeState().builder();
+        List<String> disabledIndexes2 = disabler.disableOldIndexes("/oak:index/foo", builder);
+        assertTrue(disabledIndexes2.isEmpty());
+    }
+
+    /**
+     * Test that indexes are not disabled in same cycle
+     * as when reindexing is done
+     */
+    @Test
+    public void reindexCase() throws Exception{
+        rootBuilder.child("oak:index").child("fooIndex");
+
+        builder.setProperty(IndexConstants.SUPERSEDED_INDEX_PATHS,
+                asList("/oak:index/fooIndex", "/oak:index/barIndex"), Type.STRINGS);
+        builder.setProperty(REINDEX_PROPERTY_NAME, true);
+
+        builder = builder.getNodeState().builder();
+        builder.setProperty(REINDEX_PROPERTY_NAME, false);
+
+        List<String> disabledIndexes = disabler.disableOldIndexes("/oak:index/foo", builder);
+        assertTrue(disabledIndexes.isEmpty());
+    }
+
+    @Test
+    public void nodeTypeIndexDisabling_noop() throws Exception{
+        builder.setProperty(IndexConstants.SUPERSEDED_INDEX_PATHS,
+                asList("/oak:index/fooIndex/@bar"), Type.STRINGS);
+        List<String> disabledIndexes = disabler.disableOldIndexes("/oak:index/foo", builder);
+        assertTrue(disabledIndexes.isEmpty());
+    }
+
+    @Test
+    public void nodeTypeIndexDisabling_noDeclaringTypes() throws Exception{
+        rootBuilder.child("oak:index").child("fooIndex");
+        builder.setProperty(IndexConstants.SUPERSEDED_INDEX_PATHS,
+                asList("/oak:index/fooIndex/@bar"), Type.STRINGS);
+        List<String> disabledIndexes = disabler.disableOldIndexes("/oak:index/foo", builder);
+        assertTrue(disabledIndexes.isEmpty());
+    }
+
+    @Test
+    public void nodeTypeIndexDisabling_typeNotExist() throws Exception{
+        createIndexDefinition(rootBuilder.child(INDEX_DEFINITIONS_NAME),
+                "fooIndex", true, false, ImmutableSet.of("foo"), asList("oak:TestNode"));
+        builder.setProperty(IndexConstants.SUPERSEDED_INDEX_PATHS,
+                asList("/oak:index/fooIndex/@oak:BarType"), Type.STRINGS);
+        List<String> disabledIndexes = disabler.disableOldIndexes("/oak:index/foo", builder);
+        assertTrue(disabledIndexes.isEmpty());
+    }
+
+    @Test
+    public void nodeTypeIndexDisabling_typeExist() throws Exception{
+        createIndexDefinition(rootBuilder.child(INDEX_DEFINITIONS_NAME),
+                "fooIndex", true, false, ImmutableSet.of("foo"), asList("oak:TestNode", "oak:BarType"));
+        builder.setProperty(IndexConstants.SUPERSEDED_INDEX_PATHS,
+                asList("/oak:index/fooIndex/@oak:BarType"), Type.STRINGS);
+        List<String> disabledIndexes = disabler.disableOldIndexes("/oak:index/foo", builder);
+        assertThat(disabledIndexes, containsInAnyOrder("/oak:index/fooIndex/@oak:BarType"));
+        assertTrue(builder.getBoolean(IndexConstants.DISABLED_OLD_INDEXES));
+
+        PropertyState declaringNodeType = rootBuilder.getChildNode(INDEX_DEFINITIONS_NAME).getChildNode("fooIndex").getProperty(DECLARING_NODE_TYPES);
+        assertEquals(Type.NAMES, declaringNodeType.getType());
+
+        Set<String> names = Sets.newHashSet(declaringNodeType.getValue(Type.NAMES));
+        assertThat(names, containsInAnyOrder("oak:TestNode"));
+    }
+
+}
\ No newline at end of file
