diff --git a/src/database/graph_db_accessor.hpp b/src/database/graph_db_accessor.hpp
index 05bbb26bc..2dafc2eab 100644
--- a/src/database/graph_db_accessor.hpp
+++ b/src/database/graph_db_accessor.hpp
@@ -308,6 +308,13 @@ class GraphDbAccessor {
         LabelPropertyIndex::Key(label, property));
   }
 
+  /**
+   * @brief - Returns vector of keys of label-property indices.
+   */
+  std::vector<LabelPropertyIndex::Key> GetIndicesKeys() {
+    return db_.label_property_index_.GetIndicesKeys();
+  }
+
   /**
    * Return approximate number of all vertices in the database.
    * Note that this is always an over-estimate and never an under-estimate.
diff --git a/src/database/indexes/label_property_index.hpp b/src/database/indexes/label_property_index.hpp
index 9ab8be190..3ece4d070 100644
--- a/src/database/indexes/label_property_index.hpp
+++ b/src/database/indexes/label_property_index.hpp
@@ -282,6 +282,17 @@ class LabelPropertyIndex {
         });
   }
 
+  /**
+   * @brief - Returns vector of keys of label-property indice.
+   */
+  std::vector<Key> GetIndicesKeys() {
+    std::vector<Key> indices;
+    for (auto index : indices_.access()) {
+      indices.push_back(index.first);
+    }
+    return indices;
+  }
+
  private:
   /**
    * @brief - Contains value, vlist and vertex record to distinguish between
diff --git a/src/durability/recovery.cpp b/src/durability/recovery.cpp
index 4b5e8ea0e..aba5d3113 100644
--- a/src/durability/recovery.cpp
+++ b/src/durability/recovery.cpp
@@ -25,6 +25,19 @@ bool Recovery::Decode(const fs::path &snapshot_file,
   }
   std::unordered_map<uint64_t, VertexAccessor> vertices;
 
+  query::TypedValue tv;
+  if (!decoder.ReadTypedValue(&tv, query::TypedValue::Type::List)) {
+    buffer.Close();
+    return false;
+  }
+  auto &label_property_vector = tv.Value<std::vector<query::TypedValue>>();
+  for (int i = 0; i < label_property_vector.size(); i += 2) {
+    auto label = label_property_vector[i].Value<std::string>();
+    auto property = label_property_vector[i + 1].Value<std::string>();
+    db_accessor.BuildIndex(db_accessor.label(label),
+                           db_accessor.property(property));
+  }
+
   for (int64_t i = 0; i < summary.vertex_num_; ++i) {
     communication::bolt::DecodedVertex vertex;
     if (!decoder.ReadVertex(&vertex)) {
diff --git a/src/durability/snapshooter.cpp b/src/durability/snapshooter.cpp
index 40f819dd5..fa423563d 100644
--- a/src/durability/snapshooter.cpp
+++ b/src/durability/snapshooter.cpp
@@ -33,8 +33,17 @@ bool Snapshooter::Encode(const fs::path &snapshot_file,
     // BaseEncoder encodes graph elements. Flag true is for storing vertex IDs.
     communication::bolt::BaseEncoder<FileWriterBuffer> encoder(buffer, true);
     int64_t vertex_num = 0, edge_num = 0;
-
     buffer.Open(snapshot_file);
+
+    std::vector<query::TypedValue> label_property_vector;
+    for (const auto &key : db_accessor_.GetIndicesKeys()) {
+      query::TypedValue label(*key.label_);
+      query::TypedValue property(*key.property_);
+      label_property_vector.push_back(label);
+      label_property_vector.push_back(property);
+    }
+    encoder.WriteList(label_property_vector);
+
     for (const auto &vertex : db_accessor_.vertices(false)) {
       encoder.WriteVertex(vertex);
       vertex_num++;
diff --git a/tests/unit/recovery.cpp b/tests/unit/recovery.cpp
index 5ceec8433..ee1eb8705 100644
--- a/tests/unit/recovery.cpp
+++ b/tests/unit/recovery.cpp
@@ -109,9 +109,11 @@ TEST_F(RecoveryTest, TestEncoding) {
   snapshot::Summary summary;
   buffer.Open(snapshot, summary);
 
+  query::TypedValue tv;
+  decoder.ReadTypedValue(&tv);
+
   std::vector<int64_t> ids;
   std::vector<std::string> edge_types;
-
   for (int i = 0; i < summary.vertex_num_; ++i) {
     communication::bolt::DecodedVertex vertex;
     decoder.ReadVertex(&vertex);
@@ -228,6 +230,52 @@ TEST_F(RecoveryTest, TestEncodingAndRecovering) {
   dba_get->commit();
 }
 
+TEST_F(RecoveryTest, TestLabelPropertyIndexRecovery) {
+  // Creates snapshot of the graph with indices.
+  Dbms dbms;
+  auto dba = dbms.active();
+  dba->BuildIndex(dba->label("label"), dba->property("prop"));
+  dba->commit();
+  CreateBigGraph(dbms);
+  TakeSnapshot(dbms, max_retained_snapshots_);
+  std::string snapshot = GetLatestSnapshot();
+
+  Dbms dbms_recover;
+  auto dba_recover = dbms_recover.active();
+
+  Recovery recovery;
+  EXPECT_TRUE(recovery.Recover(snapshot, *dba_recover));
+
+  auto dba_get = dbms_recover.active();
+  EXPECT_EQ(dba_get->GetIndicesKeys().size(), 1);
+  EXPECT_TRUE(dba_get->LabelPropertyIndexExists(dba_get->label("label"),
+                                                dba_get->property("prop")));
+
+  int64_t vertex_count = 0;
+  for (const auto &vertex : dba_get->vertices(false)) {
+    EXPECT_EQ(vertex.labels().size(), 1);
+    EXPECT_TRUE(vertex.has_label(dba_get->label("label")));
+    query::TypedValue prop =
+        query::TypedValue(vertex.PropsAt(dba_get->property("prop")));
+    query::TypedValue expected_prop = query::TypedValue(PropertyValue("prop"));
+    EXPECT_TRUE((prop == expected_prop).Value<bool>());
+    vertex_count++;
+  }
+  EXPECT_EQ(vertex_count, 1000);
+
+  int64_t edge_count = 0;
+  for (const auto &edge : dba_get->edges(false)) {
+    EXPECT_EQ(edge.edge_type(), dba_get->edge_type("type"));
+    query::TypedValue prop =
+        query::TypedValue(edge.PropsAt(dba_get->property("prop")));
+    query::TypedValue expected_prop = query::TypedValue(PropertyValue("prop"));
+    EXPECT_TRUE((prop == expected_prop).Value<bool>());
+    edge_count++;
+  }
+  EXPECT_EQ(edge_count, 999);
+  dba_get->commit();
+}
+
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();