diff --git a/include/query/backend/cpp_old/clause_action.hpp b/include/query/backend/cpp_old/clause_action.hpp
index 4829460e2..5c6225acb 100644
--- a/include/query/backend/cpp_old/clause_action.hpp
+++ b/include/query/backend/cpp_old/clause_action.hpp
@@ -18,5 +18,9 @@ enum class ClauseAction : uint32_t
     ReturnPack,
     ReturnProjection,
     ReturnCount,
-    ReturnLabels
+    ReturnLabels,
+    
+    UpdateEntityLabels,
+    UpdateEntityLabels_Identifier,
+    UpdateEntityLabels_Labels
 };
diff --git a/include/query/backend/cpp_old/code.hpp b/include/query/backend/cpp_old/code.hpp
index e7419147f..bae141747 100644
--- a/include/query/backend/cpp_old/code.hpp
+++ b/include/query/backend/cpp_old/code.hpp
@@ -86,15 +86,75 @@ const std::string find_and_write_vertices_by_label =
     "        stream.write_meta(\"rw\");\n";
 
 const std::string find_and_write_vertices_by_label_and_properties =
-    "{0}\n"
-    "        auto properties = query_properties(indices, args);\n"
-    "        auto &label = t.label_find_or_create(\"{1}\");\n"
-    "        stream.write_field(\"{2}\");\n"
-    "        label.index().for_range(t).properties_filter(t, properties).for_all(\n"
+    "{{\n"
+    "    DbAccessor _t(db);\n"
+    "    {0}\n"
+    "    auto properties = query_properties(indices, args);\n"
+    "    auto &label = _t.label_find_or_create(\"{1}\");\n"
+    "    stream.write_field(\"{2}\");\n"
+    "    label.index().for_range(_t).properties_filter(_t, properties).for_all(\n"
+    "    [&](auto vertex_accessor) -> void {{\n"
+    "        "+ write_vertex_accessor +
+    "    }});\n"
+    "    stream.write_meta(\"rw\");\n"
+    "    _t.commit();"
+    "}}\n";
+
+// -- LABELS
+const std::string set_vertex_element =
+    "{{\n"
+    "    DbAccessor _t(db);" // TODO: HACK (set labels should somehow persist the state)
+    "    {0}\n"
+    "    auto properties = query_properties(indices, args);\n"
+    "    auto &label = _t.label_find_or_create(\"{1}\");\n"
+    "    label.index().for_range(_t).properties_filter(_t, properties).for_all(\n"
     "        [&](auto vertex_accessor) -> void {{\n"
-    "            "+ write_vertex_accessor +
-    "        }});\n"
-    "        stream.write_meta(\"rw\");\n";
+    "            auto {2} = _t.vertex_property_key(\"{2}\", args[{3}].key.flags());\n"
+    "            vertex_accessor.set({2}, std::move(args[{3}]));\n"
+    "        }}\n"
+    "    );\n"
+    "    _t.commit();\n"
+    "}}";
+
+const std::string set_labels_start =
+    "        {{\n"
+    "            DbAccessor _t(db);" // TODO: HACK (set labels should somehow persist the state)
+    "            {0}\n"
+    "            auto properties = query_properties(indices, args);\n"
+    "            auto &label = _t.label_find_or_create(\"{1}\");\n"
+    "            label.index().for_range(_t).properties_filter(_t, properties).for_all(\n"
+    "                [&](auto vertex_accessor) -> void {{\n";
+const std::string set_label =
+    "                    auto &{0} = _t.label_find_or_create(\"{0}\");\n"
+    "                    vertex_accessor.add_label({0});\n";
+const std::string set_labels_end =
+    "                }}\n"
+    "            );\n"
+    "            _t.commit();"
+    "        }}";
+
+const std::string return_labels =
+    "{{\n"
+    "     DbAccessor _t(db);" // TODO: HACK (set labels should somehow persist the state)
+    "     {0}\n"
+    "     auto properties = query_properties(indices, args);\n"
+    "     auto &label = _t.label_find_or_create(\"{1}\");\n"
+    "     stream.write_field(\"labels({2})\");\n"
+    "     label.index().for_range(_t).properties_filter(_t, properties).for_all(\n"
+    "         [&](auto vertex_accessor) -> void {{\n"
+    "             auto &labels = vertex_accessor.labels();\n"
+    "             stream.write_record();\n"
+    "             stream.write_list_header(1);\n" // TODO: figure out why
+    "             stream.write_list_header(labels.size());\n"
+    "             for (auto &label : labels) {{\n"
+    "                 stream.write(label.get().str());\n"
+    "             }}\n"
+    "             stream.chunk();\n"
+    "         }}\n"
+    "     );\n"
+    "     stream.write_meta(\"rw\");\n"
+    "     _t.commit();\n"
+    "}}";
 
 const std::string write_all_edges =
     "stream.write_field(\"{0}\");\n"
diff --git a/include/query/backend/cpp_old/handlers/return.hpp b/include/query/backend/cpp_old/handlers/return.hpp
index 0867be83e..845388a03 100644
--- a/include/query/backend/cpp_old/handlers/return.hpp
+++ b/include/query/backend/cpp_old/handlers/return.hpp
@@ -66,8 +66,6 @@ auto return_query_action =
                 }
             }
 
-            
-
             if (cypher_data.source(entity) == EntitySource::TypeIndex)
             {
                 if (cypher_data.type(entity) == EntityType::Relationship)
@@ -116,7 +114,17 @@ auto return_query_action =
         }
         if (kv.second == ClauseAction::ReturnLabels)
         {
-            // TODO: similar to above
+            if (cypher_data.source(name) == EntitySource::LabelIndex)
+            {
+                auto tags = cypher_data.tags(name);
+                if (tags.size() == 1)
+                {
+                    auto label = tags.at(0);
+                    code += code_line(code::return_labels,
+                                      cypher_data.print_indices(name), label,
+                                      name);
+                }
+            }
         }
     }
 
diff --git a/include/query/backend/cpp_old/handlers/set.hpp b/include/query/backend/cpp_old/handlers/set.hpp
index 324411a3b..970eb0917 100644
--- a/include/query/backend/cpp_old/handlers/set.hpp
+++ b/include/query/backend/cpp_old/handlers/set.hpp
@@ -7,21 +7,66 @@ auto set_query_action = [](CypherStateData &cypher_data,
 
     std::string code = "";
 
-    for (auto const &kv : action_data.actions) {
+    for (auto const &kv : action_data.actions)
+    {
         auto name = kv.first;
 
         if (kv.second == ClauseAction::UpdateNode &&
             cypher_data.status(name) == EntityStatus::Matched &&
-            cypher_data.type(name) == EntityType::Node) {
+            cypher_data.source(name) == EntitySource::InternalId &&
+            cypher_data.type(name) == EntityType::Node)
+        {
             code += update_properties(cypher_data, action_data, name);
         }
 
+        if (kv.second == ClauseAction::UpdateNode &&
+            cypher_data.status(name) == EntityStatus::Matched &&
+            cypher_data.source(name) == EntitySource::LabelIndex &&
+            cypher_data.type(name) == EntityType::Node)
+        {
+            auto entity_data = action_data.get_entity_property(name);
+            for (auto &property : entity_data.properties)
+            {
+                auto index = action_data.parameter_index.at(
+                    ParameterIndexKey(name, property));
+                auto tmp_name = name::unique();
+                auto label    = cypher_data.tags(name).at(0);
+                // TODO: move this code inside the loop (in generated code)
+                code += code_line(code::set_vertex_element,
+                                  cypher_data.print_indices(name), label,
+                                  property, index);
+            }
+        }
+
         if (kv.second == ClauseAction::UpdateRelationship &&
             cypher_data.status(name) == EntityStatus::Matched &&
-            cypher_data.type(name) == EntityType::Relationship) {
+            cypher_data.type(name) == EntityType::Relationship)
+        {
             code += update_properties(cypher_data, action_data, name);
         }
     }
 
+    for (auto const &set_entity_labels : action_data.label_set_elements)
+    {
+        auto &entity = set_entity_labels.entity;
+
+        if (cypher_data.status(entity) == EntityStatus::Matched &&
+            cypher_data.source(entity) == EntitySource::LabelIndex)
+        {
+            auto label = cypher_data.tags(entity).at(0);
+            if (cypher_data.has_properties(entity))
+            {
+                code += code_line(code::set_labels_start,
+                                  cypher_data.print_indices(entity), label);
+                auto labels = set_entity_labels.labels;
+                for (auto const &set_label : labels)
+                {
+                    code += code_line(code::set_label, set_label);
+                }
+                code += code_line(code::set_labels_end);
+            }
+        }
+    }
+
     return code;
 };
diff --git a/include/query/backend/cpp_old/query_action_data.hpp b/include/query/backend/cpp_old/query_action_data.hpp
index 1ef09db1c..faa7db64a 100644
--- a/include/query/backend/cpp_old/query_action_data.hpp
+++ b/include/query/backend/cpp_old/query_action_data.hpp
@@ -111,6 +111,22 @@ struct ReturnElement
     bool is_projection() const { return has_entity() && has_property(); }
 };
 
+struct LabelSetElement
+{     
+    std::string entity;
+    std::vector<std::string> labels;
+    
+    LabelSetElement() = default;
+    LabelSetElement(const LabelSetElement&) = default;
+    LabelSetElement(LabelSetElement&&) = default;
+
+    void clear()
+    {
+        entity.clear();
+        labels.clear();
+    }
+};
+
 struct QueryActionData
 {
     std::map<ParameterIndexKey, uint64_t> parameter_index;
@@ -118,6 +134,7 @@ struct QueryActionData
     std::map<std::string, EntityData> entity_data;
     std::map<std::string, RelationshipData> relationship_data;
     std::vector<ReturnElement> return_elements;
+    std::vector<LabelSetElement> label_set_elements;
     bool is_detach;
     CypherStateMachine csm;
 
diff --git a/include/query/frontend/cypher/traverser.hpp b/include/query/frontend/cypher/traverser.hpp
index d64660e47..8ca89f083 100644
--- a/include/query/frontend/cypher/traverser.hpp
+++ b/include/query/frontend/cypher/traverser.hpp
@@ -30,8 +30,8 @@ struct SetElementState
     void clear()
     {
         set_entity = "";
-        set_prop = "";
-        set_index = -1;
+        set_prop   = "";
+        set_index  = -1;
     }
 };
 
@@ -52,7 +52,7 @@ struct PropertyState
 
     void clear()
     {
-        property_name = "";
+        property_name  = "";
         property_index = -1;
     }
 };
@@ -79,6 +79,7 @@ private:
     RelationshipData::Direction direction;
 
     SetElementState set_element_state;
+    LabelSetElement labels_set_element;
     PropertyState property_state;
 
     void clear_state()
@@ -95,7 +96,9 @@ private:
     void finish_query_execution()
     {
         generator.add_action(QueryAction::TransactionCommit);
+
         code += generator.generate();
+
         generator.clear();
     }
 
@@ -182,7 +185,7 @@ public:
         code += generator.generate();
         generator.add_action(QueryAction::Create);
 
-        state = CypherState::Create;
+        state        = CypherState::Create;
         query_action = QueryAction::Create;
 
         Traverser::visit(ast_create);
@@ -194,10 +197,12 @@ public:
 
         generator.add_action(QueryAction::Set);
 
-        state = CypherState::Set;
+        state        = CypherState::Set;
         query_action = QueryAction::Set;
 
         Traverser::visit(ast_set);
+
+        code += generator.generate();
     }
 
     void visit(ast::Return &ast_return) override
@@ -206,7 +211,7 @@ public:
 
         generator.add_action(QueryAction::Return);
 
-        state = CypherState::Return;
+        state        = CypherState::Return;
         query_action = QueryAction::Return;
 
         Traverser::visit(ast_return);
@@ -225,11 +230,14 @@ public:
     void visit(ast::Pattern &ast_pattern) override
     {
         // TODO: Is that traversal order OK for all cases? Probably NOT.
-        if (ast_pattern.has_next()) {
+        if (ast_pattern.has_next())
+        {
             visit(*ast_pattern.next);
             visit(*ast_pattern.node);
             visit(*ast_pattern.relationship);
-        } else {
+        }
+        else
+        {
             Traverser::visit(ast_pattern);
         }
     }
@@ -242,17 +250,22 @@ public:
         if (!ast_node.has_identifier()) return;
 
         auto name = ast_node.idn->name;
-        entity = name;
+        entity    = name;
         visited_nodes.push_back(name);
 
-        if (state == CypherState::Match) {
+        if (state == CypherState::Match)
+        {
             action_data.actions[name] = ClauseAction::MatchNode;
         }
 
-        if (state == CypherState::Create) {
-            if (cypher_data.status(name) == EntityStatus::Matched) {
+        if (state == CypherState::Create)
+        {
+            if (cypher_data.status(name) == EntityStatus::Matched)
+            {
                 action_data.actions[name] = ClauseAction::MatchNode;
-            } else {
+            }
+            else
+            {
                 action_data.actions[name] = ClauseAction::CreateNode;
             }
         }
@@ -260,7 +273,8 @@ public:
         Traverser::visit(ast_node);
 
         if (cypher_data.status(name) != EntityStatus::Matched &&
-            state == CypherState::Create) {
+            state == CypherState::Create)
+        {
             cypher_data.node_created(name);
         }
     }
@@ -286,9 +300,9 @@ public:
     // -- RELATIONSHIP --
     void create_relationship(const std::string &name)
     {
-        auto &data = generator.action_data();
+        auto &data         = generator.action_data();
         data.actions[name] = ClauseAction::CreateRelationship;
-        auto nodes = visited_nodes.last_two();
+        auto nodes         = visited_nodes.last_two();
         data.relationship_data.emplace(name,
                                        RelationshipData(nodes, direction));
     }
@@ -301,7 +315,7 @@ public:
         if (!ast_relationship.has_name()) return;
         entity = ast_relationship.name();
 
-        using ast_direction = ast::Relationship::Direction;
+        using ast_direction       = ast::Relationship::Direction;
         using generator_direction = RelationshipData::Direction;
 
         if (ast_relationship.direction == ast_direction::Left)
@@ -313,15 +327,19 @@ public:
         // TODO: add suport for Direction::Both
 
         // TODO: simplify somehow
-        if (state == CypherState::Create) {
-            if (!cypher_data.exist(entity)) {
+        if (state == CypherState::Create)
+        {
+            if (!cypher_data.exist(entity))
+            {
                 clause_action = ClauseAction::CreateRelationship;
                 create_relationship(entity);
             }
         }
 
-        if (state == CypherState::Match) {
-            if (!cypher_data.exist(entity)) {
+        if (state == CypherState::Match)
+        {
+            if (!cypher_data.exist(entity))
+            {
                 action_data.actions[entity] = ClauseAction::MatchRelationship;
             }
         }
@@ -331,20 +349,25 @@ public:
 
     void visit(ast::RelationshipSpecs &ast_relationship_specs) override
     {
-        if (state == CypherState::Match) {
-            if (ast_relationship_specs.has_identifier()) {
-                auto name = ast_relationship_specs.name();
+        if (state == CypherState::Match)
+        {
+            if (ast_relationship_specs.has_identifier())
+            {
+                auto name         = ast_relationship_specs.name();
                 auto &cypher_data = generator.cypher_data();
-                if (!cypher_data.exist(name)) {
-                    clause_action = ClauseAction::MatchRelationship;
-                    auto &data = generator.action_data();
+                if (!cypher_data.exist(name))
+                {
+                    clause_action      = ClauseAction::MatchRelationship;
+                    auto &data         = generator.action_data();
                     data.actions[name] = ClauseAction::MatchRelationship;
                 }
             }
         }
 
-        if (state == CypherState::Create) {
-            if (ast_relationship_specs.has_identifier()) {
+        if (state == CypherState::Create)
+        {
+            if (ast_relationship_specs.has_identifier())
+            {
                 entity = ast_relationship_specs.name();
             }
         }
@@ -356,7 +379,8 @@ public:
     {
         auto &action_data = generator.action_data();
 
-        if (ast_relationship_type_list.has_value()) {
+        if (ast_relationship_type_list.has_value())
+        {
             auto type = ast_relationship_type_list.value->name;
             action_data.add_entity_tag(entity, type);
             action_data.csm.search_cost(entity,
@@ -369,6 +393,13 @@ public:
 
     void visit(ast::LabelList &ast_label_list) override
     {
+        if (state == CypherState::Set)
+        {
+            clause_action = ClauseAction::UpdateEntityLabels_Labels;
+            Traverser::visit(ast_label_list);
+            return;
+        }
+
         auto &action_data = generator.action_data();
         auto &cypher_data = generator.cypher_data();
 
@@ -398,12 +429,13 @@ public:
         Traverser::visit(ast_property);
 
         // TODO: too ugly refactor somehow (clear_state part is awful)
-        if (entity.empty() || !property_state.is_defined()) {
+        if (entity.empty() || !property_state.is_defined())
+        {
             clear_state();
             return;
         }
 
-        auto prop = property_state.property_name;
+        auto prop  = property_state.property_name;
         auto index = property_state.property_index;
 
         // update action data
@@ -423,20 +455,33 @@ public:
     {
         property_state.property_name = ast_identifier.name;
 
-        if (state == CypherState::Delete) {
+        if (state == CypherState::Delete)
+        {
             auto &action_data = generator.action_data();
-            auto name = ast_identifier.name;
+            auto name         = ast_identifier.name;
             auto &cypher_data = generator.cypher_data();
             if (cypher_data.type(name) == EntityType::Node)
                 action_data.actions[name] = ClauseAction::DeleteNode;
             if (cypher_data.type(name) == EntityType::Relationship)
                 action_data.actions[name] = ClauseAction::DeleteRelationship;
         }
+
+        if (state == CypherState::Set &&
+            clause_action == ClauseAction::UpdateEntityLabels_Identifier)
+        {
+            labels_set_element.entity = ast_identifier.name;
+        }
+
+        if (state == CypherState::Set &&
+            clause_action == ClauseAction::UpdateEntityLabels_Labels)
+        {
+            labels_set_element.labels.emplace_back(ast_identifier.name);
+        }
     }
 
     void visit(ast::Long &ast_long) override
     {
-        set_element_state.set_index = ast_long.value;
+        set_element_state.set_index   = ast_long.value;
         property_state.property_index = ast_long.value;
     }
 
@@ -454,17 +499,18 @@ public:
     {
         Traverser::visit(ast_set_element);
 
-        if (!set_element_state.is_defined()) {
+        if (!set_element_state.is_defined())
+        {
             clear_state();
             return;
         }
 
         auto entity = set_element_state.set_entity;
-        auto prop = set_element_state.set_prop;
-        auto index = set_element_state.set_index;
+        auto prop   = set_element_state.set_prop;
+        auto index  = set_element_state.set_index;
 
         auto &cypher_data = generator.cypher_data();
-        auto entity_type = cypher_data.type(entity);
+        auto entity_type  = cypher_data.type(entity);
 
         if (entity_type == EntityType::None)
             throw CypherSemanticError("Entity (" + entity + ") doesn't exist");
@@ -489,12 +535,16 @@ public:
 
         auto &action_data = generator.action_data();
 
-        if (state == CypherState::Return) {
+        if (state == CypherState::Return)
+        {
             auto &return_elements = action_data.return_elements;
-            auto &entity = ast_accessor.entity_name();
-            if (!ast_accessor.has_prop()) {
+            auto &entity          = ast_accessor.entity_name();
+            if (!ast_accessor.has_prop())
+            {
                 return_elements.emplace_back(ReturnElement(entity));
-            } else {
+            }
+            else
+            {
                 auto &property = ast_accessor.entity_prop();
                 return_elements.emplace_back(ReturnElement(entity, property));
             }
@@ -502,9 +552,10 @@ public:
 
         if (!ast_accessor.has_prop()) return;
 
-        if (state == CypherState::Set) {
+        if (state == CypherState::Set)
+        {
             set_element_state.set_entity = ast_accessor.entity_name();
-            set_element_state.set_prop = ast_accessor.entity_prop();
+            set_element_state.set_prop   = ast_accessor.entity_prop();
         }
     }
 
@@ -513,6 +564,21 @@ public:
         Traverser::visit(ast_set_value);
     }
 
+    void visit(ast::LabelSetElement &ast_label_set_element) override
+    {
+        clause_action = ClauseAction::UpdateEntityLabels_Identifier;
+
+        labels_set_element.clear();
+
+        Traverser::visit(ast_label_set_element);
+
+        auto &action_data = generator.action_data();
+
+        action_data.label_set_elements.emplace_back(std::move(labels_set_element));
+
+        clause_action = ClauseAction::Undefined;
+    }
+
     void visit(ast::Delete &ast_delete) override
     {
         code += generator.generate();
@@ -536,4 +602,10 @@ public:
         action_data.actions[ast_count.argument] = ClauseAction::ReturnCount;
         // }
     }
+
+    void visit(ast::LabelsFunction &ast_label) override
+    {
+        auto &action_data = generator.action_data();
+        action_data.actions[ast_label.argument] = ClauseAction::ReturnLabels;
+    }
 };
diff --git a/include/query/language/cypher/ast/ast_visitor.hpp b/include/query/language/cypher/ast/ast_visitor.hpp
index 2cb8fb2d3..aa130d966 100644
--- a/include/query/language/cypher/ast/ast_visitor.hpp
+++ b/include/query/language/cypher/ast/ast_visitor.hpp
@@ -70,6 +70,7 @@ struct ReadWriteQuery;
 struct SetKey;
 struct SetValue;
 struct SetElement;
+struct LabelSetElement;
 struct SetList;
 
 struct WithList;
@@ -87,8 +88,8 @@ struct AstVisitor
           PatternList, Match, ReadQuery, Start, Where, WriteQuery, Create,
           Return, Distinct, Delete, DeleteQuery, UpdateQuery, Set, SetKey,
           ReadWriteQuery, IdentifierList, WithList, WithClause, WithQuery, Long,
-          CountFunction, LabelsFunction,
-          InternalIdExpr, SetValue, SetElement, SetList>
+          CountFunction, LabelsFunction, InternalIdExpr, SetValue, SetElement,
+          LabelSetElement, SetList>
 {
 };
 }
diff --git a/include/query/language/cypher/ast/set.hpp b/include/query/language/cypher/ast/set.hpp
index c7e50887a..8ba49ad37 100644
--- a/include/query/language/cypher/ast/set.hpp
+++ b/include/query/language/cypher/ast/set.hpp
@@ -35,7 +35,19 @@ struct SetValue : public AstNode<SetValue>
     bool has_value() const { return value != nullptr; }
 };
 
-struct SetElement : public AstNode<SetElement>
+struct SetElementBase : public AstVisitable
+{
+};
+
+template <class Derived>
+struct SetElementDerivedBase : public Crtp<Derived>, public SetElementBase
+{
+    using uptr = std::unique_ptr<Derived>;
+
+    virtual void accept(AstVisitor &visitor) { visitor.visit(this->derived()); }
+};
+
+struct SetElement : public SetElementDerivedBase<SetElement>
 {
     SetElement(Accessor* accessor, SetValue* set_value)
         : accessor(accessor), set_value(set_value) {}
@@ -47,7 +59,19 @@ struct SetElement : public AstNode<SetElement>
     bool has_value() const { return set_value != nullptr; }
 };
 
-struct SetList : public List<SetElement, SetList>
+struct LabelSetElement : public SetElementDerivedBase<LabelSetElement>
+{
+    LabelSetElement(Identifier* identifier, LabelList* label_list)
+        : identifier(identifier), label_list(label_list) {}
+
+    Identifier* identifier;
+    LabelList* label_list;
+
+    bool has_identifier() const { return identifier != nullptr; }
+    bool has_label_list() const { return label_list != nullptr; }
+};
+
+struct SetList : public List<SetElementBase, SetList>
 {
     using List::List;
 };
diff --git a/include/query/language/cypher/cypher.y b/include/query/language/cypher/cypher.y
index fa3e81085..8dfaee29a 100644
--- a/include/query/language/cypher/cypher.y
+++ b/include/query/language/cypher/cypher.y
@@ -544,12 +544,16 @@ set_list(L) ::= set_element(E). {
     L = ast->create<ast::SetList>(E, nullptr);
 }
 
-%type set_element {ast::SetElement*}
+%type set_element {ast::SetElementBase*}
 
 set_element(E) ::= accessor(A) EQ set_value(V). {
     E = ast->create<ast::SetElement>(A, V);
 }
 
+set_element(E) ::= idn(I) label_idn(L). {
+    E = ast->create<ast::LabelSetElement>(I, L);
+}
+
 %type accessor {ast::Accessor*}
 
 accessor(A) ::= idn(E) DOT idn(P). {
diff --git a/include/query/language/cypher/debug/tree_print.hpp b/include/query/language/cypher/debug/tree_print.hpp
index 89f29b7e2..6d555f940 100644
--- a/include/query/language/cypher/debug/tree_print.hpp
+++ b/include/query/language/cypher/debug/tree_print.hpp
@@ -395,6 +395,12 @@ public:
         Traverser::visit(set_element);
     }
 
+    void visit(ast::LabelSetElement &label_set_element) override
+    {
+        auto entry = printer.advance("Label Set Element");
+        Traverser::visit(label_set_element);
+    }
+
     void visit(ast::SetList &set_list) override
     {
         auto entry = printer.advance("Set List");
diff --git a/include/query/language/cypher/visitor/traverser.hpp b/include/query/language/cypher/visitor/traverser.hpp
index be1d3cc92..d73ffe026 100644
--- a/include/query/language/cypher/visitor/traverser.hpp
+++ b/include/query/language/cypher/visitor/traverser.hpp
@@ -244,6 +244,12 @@ public:
         accept(set_element.set_value);
     }
 
+    void visit(ast::LabelSetElement& label_set_element) override
+    {
+        accept(label_set_element.identifier);
+        accept(label_set_element.label_list);
+    }
+
     void visit(ast::SetList& set_list) override
     {
         accept(set_list.value);
diff --git a/tests/integration/scenario.py b/tests/integration/scenario.py
index 1c0d7a0e1..91d011739 100644
--- a/tests/integration/scenario.py
+++ b/tests/integration/scenario.py
@@ -4,18 +4,21 @@
 import logging
 
 # TODO: auto import
-from scenario import no_000001 
+# TODO: better logging (scenario visibility)
+# TODO: result storage
+from scenario import no_000001, no_000002
 from neo4j.v1 import GraphDatabase, basic_auth, types, Node
 
-scenarios = [no_000001.scenario_1]
+# scenarios = [no_000001.scenario_1, no_000002.scenario_2]
+scenarios = [no_000002.scenario_2]
 
 # logging init
 log = logging.getLogger(__name__)
 
 # initialize driver and create session
 session = GraphDatabase.driver("bolt://localhost",
-                              auth=basic_auth("neo4j", "1234"),
-                              encrypted=0).session()
+                               auth=basic_auth("neo4j", "1234"),
+                               encrypted=0).session()
 
 
 def check(condition, scenario_no, message):
@@ -55,6 +58,7 @@ if __name__ == "__main__":
 
 			# in case that the result is single
 			if count == 1:
+
 				# extract properties from record
 				record = records[0]
 				record_name, = record
diff --git a/tests/integration/scenario/no_000001.py b/tests/integration/scenario/no_000001.py
index 634cca994..0555264ab 100644
--- a/tests/integration/scenario/no_000001.py
+++ b/tests/integration/scenario/no_000001.py
@@ -2,6 +2,7 @@
 # -*- coding: utf-8 -*-
 
 __author__ = "Marko Budiselic"
+__date__   = "2016_11_02"
 
 class Scenario1:
     '''
diff --git a/tests/integration/scenario/no_000002.py b/tests/integration/scenario/no_000002.py
new file mode 100644
index 000000000..8befeed63
--- /dev/null
+++ b/tests/integration/scenario/no_000002.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+__author__ = "Marko Budiselic"
+__date__   = "2016_11_03"
+
+class Scenario2:
+    '''
+    Create node, edit labels and return all labels for the node.
+    '''
+
+    def __init__(self):
+        '''
+        Constructor
+        '''
+        self.no = 2
+        self.desctiption = "Create node, edit labels and return all labels for the node."
+        self.init_graph = []
+        self.queries = [
+            ("MATCH (n) DETACH DELETE n", (0, None)),
+            ("CREATE (n:Garment {garment_id: 1234, garment_category_id: 1}) RETURN n", (1, [{"garment_id": 1234, "garment_category_id": 1}])),
+            ("MATCH (g:Garment {garment_id: 1234}) SET g:FF RETURN labels(g)", (1, [["Garment", "FF"]])),
+            ("MATCH(g:Garment {garment_id: 1234}) SET g.reveals = 50 RETURN g", (1, [{"garment_id": 1234, "garment_category_id": 1, "reveals": 50}])),
+            ("MATCH (n) RETURN n", (1, [{"garment_id": 1234, "garment_category_id": 1, "reveals": 50}])),
+        ]
+        self.side_effects = None
+
+scenario_2 = Scenario2()