diff --git oak-run-commons/src/main/java/org/apache/jackrabbit/oak/fixture/OakFixture.java oak-run-commons/src/main/java/org/apache/jackrabbit/oak/fixture/OakFixture.java
index 4395d3f..1079ab7 100644
--- oak-run-commons/src/main/java/org/apache/jackrabbit/oak/fixture/OakFixture.java
+++ oak-run-commons/src/main/java/org/apache/jackrabbit/oak/fixture/OakFixture.java
@@ -19,10 +19,15 @@ package org.apache.jackrabbit.oak.fixture;
 import java.io.File;
 import java.lang.management.ManagementFactory;
 import java.net.UnknownHostException;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 import javax.sql.DataSource;
 
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
 import org.apache.jackrabbit.oak.Oak;
 import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
 import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
@@ -35,11 +40,14 @@ import org.apache.jackrabbit.oak.plugins.document.rdb.RDBOptions;
 import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.spi.filter.PathFilter;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static java.util.Collections.emptyList;
+
 public abstract class OakFixture {
 
     public static final String OAK_MEMORY = "Oak-Memory";
@@ -356,10 +364,10 @@ public abstract class OakFixture {
             DocumentMK.Builder mkBuilder = new DocumentMK.Builder().
                     setMongoDB(mongo.getDB()).
                     memoryCacheSize(cacheSize).
-                    //TODO Persistent cache should be removed in teardown
-                            setPersistentCache("target/persistentCache,time").
                             setClusterId(clusterId).
                             setLogging(false);
+
+            configurePersistentCache(mkBuilder);
             setupBlobStore(mkBuilder, StatisticsProvider.NOOP);
             return mkBuilder;
         }
@@ -427,6 +435,28 @@ public abstract class OakFixture {
             }
         }
 
+        private void configurePersistentCache(DocumentMK.Builder mkBuilder) {
+            //TODO Persistent cache should be removed in teardown
+            mkBuilder.setPersistentCache("target/persistentCache,time");
+
+            String persistentCacheIncludes = System.getProperty("persistentCacheIncludes");
+
+            Set<String> paths = new HashSet<>();
+            if (persistentCacheIncludes != null) {
+                for (String p : Splitter.on(',').split(persistentCacheIncludes)) {
+                    p = p != null ? Strings.emptyToNull(p.trim()) : null;
+                    if (p != null) {
+                        paths.add(p);
+                    }
+                }
+
+                PathFilter pf = new PathFilter(paths, emptyList());
+                System.out.println("Configuring persistent cache to only cache nodes under paths " + paths);
+                Predicate<String> cachePredicate = path -> path != null && pf.filter(path) == PathFilter.Result.INCLUDE;
+                mkBuilder.setNodeCachePredicate(cachePredicate);
+            }
+        }
+
     }
 
     static Oak newOak(NodeStore nodeStore) {
diff --git oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
index 812e2a9..0bde2ad 100644
--- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
+++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
@@ -40,6 +40,8 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.sql.DataSource;
 
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.base.Supplier;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
@@ -606,6 +608,7 @@ public class DocumentMK {
         private long maxRevisionAgeMillis = DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS;
         private GCMonitor gcMonitor = new LoggingGCMonitor(
                 LoggerFactory.getLogger(VersionGarbageCollector.class));
+        private Predicate<String> nodeCachePredicate = Predicates.alwaysTrue();
 
         public Builder() {
         }
@@ -1252,6 +1255,15 @@ public class DocumentMK {
             return new NodeDocumentCache(nodeDocumentsCache, nodeDocumentsCacheStats, prevDocumentsCache, prevDocumentsCacheStats, locks);
         }
 
+        public Builder setNodeCachePredicate(Predicate<String> p){
+            this.nodeCachePredicate = p;
+            return this;
+        }
+
+        public Predicate<String> getNodeCachePredicate() {
+            return nodeCachePredicate;
+        }
+
         @SuppressWarnings("unchecked")
         private <K extends CacheValue, V extends CacheValue> Cache<K, V> buildCache(
                 CacheType cacheType,
diff --git oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
index 83104a7..56d78cd 100644
--- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
+++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
@@ -510,7 +510,10 @@ public final class DocumentNodeStore
      */
     private final Set<Revision> inDoubtTrunkCommits = Sets.newConcurrentHashSet();
 
+    private final Predicate<String> nodeCachePredicate;
+
     public DocumentNodeStore(DocumentMK.Builder builder) {
+        this.nodeCachePredicate = builder.getNodeCachePredicate();
         this.updateLimit = builder.getUpdateLimit();
         this.commitValueResolver = new CommitValueResolver(builder.getCommitValueCacheSize(),
                 new Supplier<RevisionVector>() {
@@ -1048,6 +1051,10 @@ public final class DocumentNodeStore
         return nodeChildrenCache;
     }
 
+    public Predicate<String> getNodeCachePredicate() {
+        return nodeCachePredicate;
+    }
+
     /**
      * Returns the journal entry that will be stored in the journal with the
      * next background updated.
diff --git oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
index dd9cd68..b04abf5 100644
--- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
+++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
@@ -20,6 +20,7 @@ package org.apache.jackrabbit.oak.plugins.document;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.emptyList;
 import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly;
 import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toBoolean;
 import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toInteger;
@@ -39,17 +40,22 @@ import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerM
 import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nonnull;
 import javax.sql.DataSource;
 
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.base.Strings;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
@@ -86,6 +92,7 @@ import org.apache.jackrabbit.oak.spi.blob.BlobStoreWrapper;
 import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
 import org.apache.jackrabbit.oak.spi.blob.stats.BlobStoreStatsMBean;
 import org.apache.jackrabbit.oak.spi.commit.BackgroundObserverMBean;
+import org.apache.jackrabbit.oak.spi.filter.PathFilter;
 import org.apache.jackrabbit.oak.spi.gc.DelegatingGCMonitor;
 import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
 import org.apache.jackrabbit.oak.spi.gc.GCMonitorTracker;
@@ -361,6 +368,11 @@ public class DocumentNodeStoreService {
                 description = "Number of content updates that need to happen before " +
                         "the updates are automatically purged to the private branch.")
         int updateLimit();
+
+        @AttributeDefinition(
+                name = "Persistent Cache Includes",
+                description = "Paths which should be cached in persistent cache")
+        String[] persistentCacheIncludes() default {"/"};
     }
     
     // property name constants - values can come from framework properties or OSGi config
@@ -435,9 +447,12 @@ public class DocumentNodeStoreService {
 
     private BlobStore defaultBlobStore;
 
+    private volatile Configuration config;
+
     @Activate
     protected void activate(ComponentContext context, Configuration config) throws Exception {
         closer = Closer.create();
+        this.config = config;
         this.context = context;
         whiteboard = new OsgiWhiteboard(context.getBundleContext());
         executor = new WhiteboardExecutor();
@@ -522,7 +537,8 @@ public class DocumentNodeStoreService {
                 }).
                 setPrefetchExternalChanges(prefetchExternalChanges).
                 setUpdateLimit(updateLimit).
-                setJournalGCMaxAge(journalGCMaxAge);
+                setJournalGCMaxAge(journalGCMaxAge).
+                setNodeCachePredicate(createCachePredicate());
 
         if (!Strings.isNullOrEmpty(persistentCache)) {
             mkBuilder.setPersistentCache(persistentCache);
@@ -696,6 +712,26 @@ public class DocumentNodeStoreService {
             nodeStore, props);
     }
 
+    private Predicate<String> createCachePredicate() {
+        if (config.persistentCacheIncludes().length == 0) {
+            return Predicates.alwaysTrue();
+        }
+        if (Arrays.equals(config.persistentCacheIncludes(), new String[]{"/"})) {
+            return Predicates.alwaysTrue();
+        }
+
+        Set<String> paths = new HashSet<>();
+        for (String p : config.persistentCacheIncludes()) {
+            p = p != null ? Strings.emptyToNull(p.trim()) : null;
+            if (p != null) {
+                paths.add(p);
+            }
+        }
+        PathFilter pf = new PathFilter(paths, emptyList());
+        log.info("Configuring persistent cache to only cache nodes under paths {}", paths);
+        return path -> path != null && pf.filter(path) == PathFilter.Result.INCLUDE;
+    }
+
     private boolean isNodeStoreProvider() {
         return prop(PROP_ROLE) != null;
     }
diff --git oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java
index 41e4f19..f5e69d6 100644
--- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java
+++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java
@@ -53,7 +53,11 @@ public enum CacheType {
         }
         @Override
         public <K> boolean shouldCache(DocumentNodeStore store, K key) {
-            return !store.getNodeStateCache().isCached(((PathRev)key).getPath());
+            String path = ((PathRev) key).getPath();
+            if (!store.getNodeCachePredicate().apply(path)){
+                return false;
+            }
+            return !store.getNodeStateCache().isCached(path);
         }
     },
     
@@ -84,7 +88,11 @@ public enum CacheType {
 
         @Override
         public <K> boolean shouldCache(DocumentNodeStore store, K key) {
-            return !store.getNodeStateCache().isCached(((PathRev)key).getPath());
+            String path = ((PathRev) key).getPath();
+            if (!store.getNodeCachePredicate().apply(path)){
+                return false;
+            }
+            return !store.getNodeStateCache().isCached(path);
         }
     }, 
     
diff --git oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
index 2a0052d..30dc49f 100644
--- oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
+++ oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
@@ -189,6 +189,19 @@ public class DocumentNodeStoreServiceTest {
         assertNotNull(((Supplier) rgcJob).get());
     }
 
+    @Test
+    public void persistentCacheExclude() throws Exception{
+        Map<String, Object> config = newConfig(repoHome);
+        config.put("persistentCacheIncludes", new String[] {"/a/b", "/c/d ", null});
+        MockOsgi.activate(service, context.bundleContext(), config);
+
+        DocumentNodeStore dns = context.getService(DocumentNodeStore.class);
+        assertTrue(dns.getNodeCachePredicate().apply("/a/b/c"));
+        assertTrue(dns.getNodeCachePredicate().apply("/c/d/e"));
+
+        assertFalse(dns.getNodeCachePredicate().apply("/x"));
+    }
+
     private static MongoDocumentStore getMongoDocumentStore(DocumentNodeStore s) {
         try {
             Field f = s.getClass().getDeclaredField("nonLeaseCheckingStore");
diff --git oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java
index 8e0665b..42c1a4a 100644
--- oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java
+++ oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java
@@ -23,7 +23,9 @@ import java.io.File;
 import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.Consumer;
 
+import com.google.common.base.Predicate;
 import com.google.common.cache.RemovalCause;
 import com.google.common.collect.Lists;
 import org.apache.jackrabbit.oak.commons.concurrent.ExecutorCloser;
@@ -37,6 +39,7 @@ import org.apache.jackrabbit.oak.plugins.document.PathRev;
 import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.filter.PathFilter;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.stats.Counting;
 import org.apache.jackrabbit.oak.stats.DefaultStatisticsProvider;
@@ -46,6 +49,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -118,7 +123,32 @@ public class NodeCacheTest {
         assertNotContains(nodeChildren, "/c");
     }
 
+    @Test
+    public void cachePredicateSync() throws Exception{
+        PathFilter pf = new PathFilter(asList("/a"), emptyList());
+        Predicate<String> p = path -> pf.filter(path) == PathFilter.Result.INCLUDE;
+        initializeNodeStore(false, b -> b.setNodeCachePredicate(p));
+
+        NodeBuilder builder = ns.getRoot().builder();
+        builder.child("a").child("c1");
+        builder.child("b").child("c2");
+        ns.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+        //Do a read again
+        ns.getRoot().getChildNode("a").getChildNode("c1");
+        ns.getRoot().getChildNode("b").getChildNode("c2");
+
+        assertNotContains(nodeCache, "/b");
+        assertNotContains(nodeCache, "/b/c2");
+        assertContains(nodeCache, "/a");
+        assertContains(nodeCache, "/a/c1");
+    }
+
     private void initializeNodeStore(boolean asyncCache) {
+        initializeNodeStore(asyncCache, b -> {});
+    }
+
+    private void initializeNodeStore(boolean asyncCache, Consumer<DocumentMK.Builder> processor) {
         DocumentMK.Builder builder = builderProvider.newBuilder()
                 .setAsyncDelay(0)
                 .setStatisticsProvider(statsProvider);
@@ -128,6 +158,9 @@ public class NodeCacheTest {
         }else {
             builder.setPersistentCache("target/persistentCache,time,-async");
         }
+
+        processor.accept(builder);
+
         ns = builder.getNodeStore();
         nodeCache = (NodeCache<PathRev, DocumentNodeState>) ns.getNodeCache();
         nodeChildren = (NodeCache<PathRev, DocumentNodeState.Children>) ns.getNodeChildrenCache();
