diff --git oak-core/pom.xml oak-core/pom.xml
index 882ae83..672b794 100644
--- oak-core/pom.xml
+++ oak-core/pom.xml
@@ -40,6 +40,7 @@
           <instructions>
             <Import-Package>
               com.mongodb*;version="[2.14, 4)";resolution:=optional,
+              org.apache.felix.inventory;version="[1.0.0, 2)";resolution:=optional,
               *
             </Import-Package>
             <Export-Package>
@@ -99,6 +100,10 @@
             <DynamicImport-Package>
               org.apache.felix.jaas.boot
             </DynamicImport-Package>
+            <Private-Package>
+              {local-packages},
+              org.apache.felix.inventory
+            </Private-Package>
           </instructions>
         </configuration>
       </plugin>
@@ -268,6 +273,13 @@
       <artifactId>slf4j-api</artifactId>
     </dependency>
 
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.inventory</artifactId>
+      <version>1.0.4</version>
+      <optional>true</optional>
+    </dependency>
+
     <!-- Findbugs annotations -->
     <dependency>
       <groupId>com.google.code.findbugs</groupId>
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfo.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfo.java
new file mode 100644
index 0000000..0a417b1
--- /dev/null
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfo.java
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+import javax.annotation.CheckForNull;
+
+import aQute.bnd.annotation.ProviderType;
+
+/**
+ * Captures information related to index
+ */
+@ProviderType
+public interface IndexInfo {
+    /**
+     * Returns paths of index definition in the repository
+     */
+    String getIndexPath();
+
+    /**
+     * Returns type of index definition like 'property' or 'lucene'
+     */
+    String getType();
+
+    /**
+     * Returns name of the async index lane to which this index is bound to
+     * or null if its not an async index
+     */
+    @CheckForNull
+    String getAsyncName();
+
+    /**
+     * Time in millis at which index was last updated
+     *
+     * @return time in millis or -1 if unknown
+     */
+    long getLastUpdatedTime();
+
+    /**
+     * Returns time in millis of the repository state upto which index is upto
+     * date. This may or may not be same as {@code #getLastUpdatedTime}. For e.g.
+     * consider an index at /oak:index/fooIndex bound to async lane "async".
+     * The index might have got updated 2 cycle ago when async indexer traversed content
+     * node which were indexed by this index and it was not updated in last index cycle.
+     * Then {@code indexedUptoTime} would be the time of last complete cycle while
+     * {@code lastUpdatedTime} would the time of 2nd last cycle
+     *
+     * @return time in millis or -1 if unknown
+     */
+    long getIndexedUptoTime();
+
+    /**
+     * An estimate of entry count in the index
+     */
+    long getEstimatedEntryCount();
+
+    /**
+     * Index data storage size
+
+     * @return storage size or -1 if unknown
+     */
+    long getSizeInBytes();
+
+    /**
+     * Determines if index definition has changed but no reindexing
+     * was done for that change.
+     */
+    boolean hasIndexDefinitionChangedWithoutReindexing();
+}
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoProvider.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoProvider.java
new file mode 100644
index 0000000..f84ca87
--- /dev/null
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import javax.annotation.CheckForNull;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Service to be provided by various index implementations.
+ * This would then be used by {@code IndexInfoService}
+ * for collecting information related to index.
+ */
+@ConsumerType
+public interface IndexInfoProvider {
+
+    /**
+     * Index type for this implementation can provide information
+     */
+    String getType();
+
+    @CheckForNull
+    IndexInfo getInfo(String indexPath) throws IOException;
+
+    /**
+     * Determined if the index is valid and usable. If the index is corrupt
+     * then it returns false
+     */
+    boolean isValid(String indexPath) throws IOException;
+}
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoService.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoService.java
new file mode 100644
index 0000000..b0f8a7c
--- /dev/null
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoService.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import javax.annotation.CheckForNull;
+
+import aQute.bnd.annotation.ProviderType;
+
+@ProviderType
+public interface IndexInfoService {
+
+    /**
+     * Returns {@code IndexInfo} for all the indexes present in
+     * the repository
+     */
+    Iterable<IndexInfo> getAllIndexInfo();
+
+    /**
+     * Returns {@code IndexInfo} for index at given path
+     *
+     * @param indexPath path repository
+     *
+     * @return indexInfo for the index or null if there is no index node
+     * found at given path
+     */
+    @CheckForNull
+    IndexInfo getInfo(String indexPath) throws IOException;
+
+    /**
+     * Determined if the index is valid and usable. If the index is corrupt
+     * then it returns false
+     */
+    boolean isValid(String indexPath) throws IOException;
+}
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoServiceImpl.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoServiceImpl.java
new file mode 100644
index 0000000..f656b21
--- /dev/null
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexInfoServiceImpl.java
@@ -0,0 +1,169 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.felix.scr.annotations.ReferencePolicyOption;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Predicates.notNull;
+
+@Component
+@Service
+public class IndexInfoServiceImpl implements IndexInfoService{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Reference
+    private IndexPathService indexPathService;
+
+    @Reference(policy = ReferencePolicy.DYNAMIC,
+            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
+            policyOption = ReferencePolicyOption.GREEDY,
+            referenceInterface = IndexInfoProvider.class
+    )
+    private final Map<String, IndexInfoProvider> infoProviders = new ConcurrentHashMap<>();
+
+    @Reference
+    private NodeStore nodeStore;
+
+    @Override
+    public Iterable<IndexInfo> getAllIndexInfo() {
+        return Iterables.filter(Iterables.transform(indexPathService.getIndexPaths(), new Function<String, IndexInfo>() {
+            @Override
+            public IndexInfo apply(String indexPath) {
+
+                try {
+                    return getInfo(indexPath);
+                } catch (IOException e) {
+                    log.warn("Error occurred while capturing IndexInfo for path {}", indexPath, e);
+                    return null;
+                }
+            }
+        }), notNull());
+    }
+
+    @Override
+    public IndexInfo getInfo(String indexPath) throws IOException {
+        String type = getIndexType(indexPath);
+        if (type == null) return null;
+        IndexInfoProvider infoProvider = infoProviders.get(type);
+
+        if (infoProvider == null) {
+            return new SimpleIndexInfo(indexPath, type);
+        }
+
+        return infoProvider.getInfo(indexPath);
+    }
+
+    @Override
+    public boolean isValid(String indexPath) throws IOException {
+        String type = getIndexType(indexPath);
+        if (type == null){
+            log.warn("No type property defined for index definition at path {}", indexPath);
+            return false;
+        }
+        IndexInfoProvider infoProvider = infoProviders.get(type);
+        if (infoProvider == null){
+            log.warn("No IndexInfoProvider for for index definition at path {} of type {}", indexPath, type);
+            return true; //TODO Reconsider this scenario
+        }
+        return infoProvider.isValid(indexPath);
+    }
+
+    protected void bindInfoProviders(IndexInfoProvider infoProvider){
+        infoProviders.put(infoProvider.getType(), infoProvider);
+    }
+
+    protected void unbindInfoProviders(IndexInfoProvider infoProvider){
+        infoProviders.remove(infoProvider.getType());
+    }
+
+    private String getIndexType(String indexPath) {
+        NodeState idxState = NodeStateUtils.getNode(nodeStore.getRoot(), indexPath);
+        String type = idxState.getString(IndexConstants.TYPE_PROPERTY_NAME);
+        if (type == null || "disabled".equals(type)){
+            return null;
+        }
+        return type;
+    }
+
+    private static class SimpleIndexInfo implements IndexInfo {
+        private final String indexPath;
+        private final String type;
+
+        private SimpleIndexInfo(String indexPath, String type) {
+            this.indexPath = indexPath;
+            this.type = type;
+        }
+
+        @Override
+        public String getIndexPath() {
+            return indexPath;
+        }
+
+        @Override
+        public String getType() {
+            return type;
+        }
+
+        @Override
+        public String getAsyncName() {
+            return null;
+        }
+
+        @Override
+        public long getLastUpdatedTime() {
+            return -1;        }
+
+        @Override
+        public long getIndexedUptoTime() {
+            return -1;
+        }
+
+        @Override
+        public long getEstimatedEntryCount() {
+            return -1;
+        }
+
+        @Override
+        public long getSizeInBytes() {
+            return -1;
+        }
+
+        @Override
+        public boolean hasIndexDefinitionChangedWithoutReindexing() {
+            return false;
+        }
+    }
+}
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexPrinter.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexPrinter.java
new file mode 100644
index 0000000..7820064
--- /dev/null
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexPrinter.java
@@ -0,0 +1,131 @@
+/*
+ * 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;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ListMultimap;
+import org.apache.felix.inventory.Format;
+import org.apache.felix.inventory.InventoryPrinter;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.api.jmx.IndexStatsMBean;
+import org.apache.jackrabbit.oak.commons.IOUtils;
+
+@Component
+@Service
+@Properties({
+        @Property(name = "felix.inventory.printer.name", value = "oak-indexes"),
+        @Property(name = "felix.inventory.printer.title", value = "Oak Indexes"),
+        @Property(name = "felix.inventory.printer.format", value = { "TEXT"})
+})
+public class IndexPrinter implements InventoryPrinter {
+
+    @Reference
+    private IndexInfoService indexInfoService;
+
+    @Reference
+    private AsyncIndexInfoService asyncIndexInfoService;
+
+    @Override
+    public void print(PrintWriter pw, Format format, boolean isZip) {
+        //TODO Highlight if failing
+        printAsyncIndexInfo(pw);
+        printIndexInfo(pw);
+    }
+
+    private void printAsyncIndexInfo(PrintWriter pw) {
+        List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
+        String title = "Async Indexers State";
+        printTitle(pw, title);
+        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
+        pw.println();
+        for (String lane : asyncLanes) {
+            pw.println(lane);
+            AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            if (info != null) {
+                        pw.printf("    Last Indexed To      : %tc%n", info.getLastIndexedTo());
+                IndexStatsMBean stats = info.getStatsMBean();
+                if (stats != null) {
+                        pw.printf("    Status              : %s%n", stats.getStatus());
+                        pw.printf("    Failing             : %s%n", stats.isFailing());
+                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    if (stats.isFailing()) {
+                        pw.printf("    Failing Since       : %s%n", stats.getFailingSince());
+                        pw.printf("    Latest Error        : %s%n", stats.getLatestError());
+                    }
+                }
+                pw.println();
+            }
+        }
+    }
+
+    private static void printTitle(PrintWriter pw, String title) {
+        pw.println(title);
+        pw.println(Strings.repeat("=", title.length()));
+    }
+
+    private void printIndexInfo(PrintWriter pw) {
+        ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
+        for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
+            infos.put(info.getType(), info);
+        }
+
+        pw.printf("Total number of indexes : %d%n", infos.size());
+        for (String type : infos.keySet()){
+            List<IndexInfo> typedInfo = infos.get(type);
+            String title = String.format("%s(%d)", type, typedInfo.size());
+            printTitle(pw, title);
+            pw.println();
+            for (IndexInfo info : typedInfo){
+                printIndexInfo(pw, info);
+            }
+        }
+    }
+
+    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
+        pw.println(info.getIndexPath());
+        pw.printf("    Type                    : %s%n", info.getType());
+        if (info.getAsyncName() != null) {
+            pw.printf("    async                   : true%n");
+            pw.printf("    async name              : %s%n", info.getAsyncName());
+        }
+
+        if (info.getIndexedUptoTime() > 0){
+            pw.printf("    Last Indexed Upto       : %tc%n", info.getIndexedUptoTime());
+        }
+
+        if (info.getSizeInBytes() > 0){
+            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+        }
+
+        if (info.getEstimatedEntryCount() > 0){
+            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+        }
+        pw.println();
+    }
+}
diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexInfoProvider.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexInfoProvider.java
new file mode 100644
index 0000000..f7a2ae1
--- /dev/null
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexInfoProvider.java
@@ -0,0 +1,165 @@
+/*
+ * 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.lucene;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfo;
+import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfoService;
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.IndexInfo;
+import org.apache.jackrabbit.oak.plugins.index.IndexInfoProvider;
+import org.apache.jackrabbit.oak.plugins.index.lucene.directory.DirectoryUtils;
+import org.apache.jackrabbit.oak.plugins.index.lucene.directory.IndexConsistencyChecker;
+import org.apache.jackrabbit.oak.plugins.index.lucene.writer.MultiplexersLucene;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.spi.state.ReadOnlyBuilder;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.store.Directory;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class LuceneIndexInfoProvider implements IndexInfoProvider {
+
+    private final NodeStore nodeStore;
+
+    private final AsyncIndexInfoService asyncInfoService;
+
+    private final File workDir;
+
+    public LuceneIndexInfoProvider(NodeStore nodeStore, AsyncIndexInfoService asyncInfoService, File workDir) {
+        this.nodeStore = checkNotNull(nodeStore);
+        this.asyncInfoService = checkNotNull(asyncInfoService);
+        this.workDir = checkNotNull(workDir);
+    }
+
+    @Override
+    public String getType() {
+        return LuceneIndexConstants.TYPE_LUCENE;
+    }
+
+    @Override
+    public IndexInfo getInfo(String indexPath) throws IOException {
+        NodeState idxState = NodeStateUtils.getNode(nodeStore.getRoot(), indexPath);
+        LuceneIndexInfo info = new LuceneIndexInfo(indexPath);
+        computeSize(idxState, info);
+        computeAsyncIndexInfo(idxState, indexPath, info);
+        return info;
+    }
+
+    @Override
+    public boolean isValid(String indexPath) throws IOException {
+        IndexConsistencyChecker checker = new IndexConsistencyChecker(nodeStore.getRoot(), indexPath, workDir);
+        return checker.check(IndexConsistencyChecker.Level.BLOBS_ONLY).clean;
+    }
+
+    private void computeAsyncIndexInfo(NodeState idxState, String indexPath, LuceneIndexInfo info) {
+        String asyncName = getAsyncName(idxState, indexPath);
+        AsyncIndexInfo asyncInfo = asyncInfoService.getInfo(asyncName);
+        checkNotNull(asyncInfo, "No async info found for name [%s] " +
+                "for index at [%s]", asyncName, indexPath);
+        info.indexedUptoTime = asyncInfo.getLastIndexedTo();
+        info.asyncName = asyncName;
+    }
+
+    static String getAsyncName(NodeState idxState, String indexPath) {
+        if (idxState.hasProperty(IndexConstants.ASYNC_PROPERTY_NAME)) {
+            Set<String> asyncNames = Sets.newHashSet(idxState.getStrings(IndexConstants.ASYNC_PROPERTY_NAME));
+            asyncNames.remove(IndexConstants.INDEXING_MODE_NRT);
+            asyncNames.remove(IndexConstants.INDEXING_MODE_SYNC);
+            checkArgument(!asyncNames.isEmpty(), "No valid async name found for " +
+                    "index [%s], definition %s", indexPath, idxState);
+            return Iterables.getOnlyElement(asyncNames);
+        }
+        return null;
+    }
+
+    private void computeSize(NodeState idxState, LuceneIndexInfo info) throws IOException {
+        IndexDefinition defn = IndexDefinition.newBuilder(nodeStore.getRoot(), idxState, info.indexPath).build();
+        for (String dirName : idxState.getChildNodeNames()) {
+            if (NodeStateUtils.isHidden(dirName) && MultiplexersLucene.isIndexDirName(dirName)) {
+                Directory dir = new OakDirectory(new ReadOnlyBuilder(idxState), dirName, defn, true);
+                try (DirectoryReader dirReader = DirectoryReader.open(dir)) {
+                    info.numEntries += dirReader.numDocs();
+                    info.size = DirectoryUtils.dirSize(dir);
+                }
+            }
+        }
+    }
+
+    private static class LuceneIndexInfo implements IndexInfo {
+        String indexPath;
+        String asyncName;
+        long numEntries;
+        long size;
+        long indexedUptoTime;
+
+        public LuceneIndexInfo(String indexPath) {
+            this.indexPath = indexPath;
+        }
+
+        @Override
+        public String getIndexPath() {
+            return indexPath;
+        }
+
+        @Override
+        public String getType() {
+            return LuceneIndexConstants.TYPE_LUCENE;
+        }
+
+        @Override
+        public String getAsyncName() {
+            return asyncName;
+        }
+
+        @Override
+        public long getLastUpdatedTime() {
+            return 0; //TODO To be computed
+        }
+
+        @Override
+        public long getIndexedUptoTime() {
+            return indexedUptoTime;
+        }
+
+        @Override
+        public long getEstimatedEntryCount() {
+            return numEntries;
+        }
+
+        @Override
+        public long getSizeInBytes() {
+            return size;
+        }
+
+        @Override
+        public boolean hasIndexDefinitionChangedWithoutReindexing() {
+            return false; //TODO To be computed
+        }
+    }
+}
diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
index 15f5897..495186b 100644
--- oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
@@ -51,7 +51,9 @@ import org.apache.jackrabbit.oak.cache.CacheStats;
 import org.apache.jackrabbit.oak.commons.PropertiesUtil;
 import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
 import org.apache.jackrabbit.oak.plugins.document.spi.JournalPropertyService;
+import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfoService;
 import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
+import org.apache.jackrabbit.oak.plugins.index.IndexInfoProvider;
 import org.apache.jackrabbit.oak.plugins.index.IndexPathService;
 import org.apache.jackrabbit.oak.plugins.index.aggregate.NodeAggregator;
 import org.apache.jackrabbit.oak.plugins.index.fulltext.PreExtractedTextProvider;
@@ -260,6 +262,9 @@ public class LuceneIndexProviderService {
     @Reference
     private IndexPathService indexPathService;
 
+    @Reference
+    private AsyncIndexInfoService asyncIndexInfoService;
+
     @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY,
         policyOption = ReferencePolicyOption.GREEDY,
         policy = ReferencePolicy.DYNAMIC
@@ -311,15 +316,20 @@ public class LuceneIndexProviderService {
         registerObserver(bundleContext, config);
         registerLocalIndexObserver(bundleContext, tracker, config);
         registerIndexEditor(bundleContext, tracker, config);
+        registerIndexInfoProvider(bundleContext);
 
         oakRegs.add(registerMBean(whiteboard,
                 LuceneIndexMBean.class,
-                new LuceneIndexMBeanImpl(indexProvider.getTracker(), nodeStore, indexPathService, new File(indexDir, "indexCheckDir")),
+                new LuceneIndexMBeanImpl(indexProvider.getTracker(), nodeStore, indexPathService, getIndexCheckDir()),
                 LuceneIndexMBean.TYPE,
                 "Lucene Index statistics"));
         registerGCMonitor(whiteboard, indexProvider.getTracker());
     }
 
+    private File getIndexCheckDir() {
+        return new File(checkNotNull(indexDir), "indexCheckDir");
+    }
+
     @Deactivate
     private void deactivate() throws InterruptedException, IOException {
         for (ServiceRegistration reg : regs) {
@@ -661,6 +671,11 @@ public class LuceneIndexProviderService {
         }
     }
 
+    private void registerIndexInfoProvider(BundleContext bundleContext) {
+        IndexInfoProvider infoProvider = new LuceneIndexInfoProvider(nodeStore, asyncIndexInfoService, getIndexCheckDir());
+        regs.add(bundleContext.registerService(IndexInfoProvider.class.getName(), infoProvider, null));
+    }
+
     protected void bindNodeAggregator(NodeAggregator aggregator) {
         this.nodeAggregator = aggregator;
         initialize();
diff --git oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java
index 4b3747a..c88a19f 100644
--- oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java
+++ oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java
@@ -39,6 +39,7 @@ import org.apache.jackrabbit.oak.plugins.blob.datastore.CachingFileDataStore;
 import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore;
 import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreUtils;
 import org.apache.jackrabbit.oak.plugins.document.spi.JournalPropertyService;
+import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfoService;
 import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
 import org.apache.jackrabbit.oak.plugins.index.IndexPathService;
 import org.apache.jackrabbit.oak.plugins.index.fulltext.ExtractedText;
@@ -86,6 +87,7 @@ public class LuceneIndexProviderServiceTest {
         context.registerService(IndexAugmentorFactory.class, mock(IndexAugmentorFactory.class));
         context.registerService(NodeStore.class, new MemoryNodeStore());
         context.registerService(IndexPathService.class, mock(IndexPathService.class));
+        context.registerService(AsyncIndexInfoService.class, mock(AsyncIndexInfoService.class));
         MockOsgi.injectServices(service, context.bundleContext());
     }
 
