diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index a3b1701..6c2bf6c 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -286,8 +286,9 @@
    * @return None.
    */
   template <typename CallbackFunc>
-  void changeVlanId(const std::string &ifaceId, const uint32_t &inputVlanId,
-                    CallbackFunc &&callback) {
+  static void changeVlanId(const std::string &ifaceId,
+                           const uint32_t &inputVlanId,
+                           CallbackFunc &&callback) {
     crow::connections::system_bus->async_method_call(
         callback, "xyz.openbmc_project.Network",
         std::string("/xyz/openbmc_project/network/") + ifaceId,
@@ -491,7 +492,7 @@
    * @return None.
    */
   template <typename CallbackFunc>
-  void disableVlan(const std::string &ifaceId, CallbackFunc &&callback) {
+  static void disableVlan(const std::string &ifaceId, CallbackFunc &&callback) {
     crow::connections::system_bus->async_method_call(
         callback, "xyz.openbmc_project.Network",
         std::string("/xyz/openbmc_project/network/") + ifaceId,
@@ -826,27 +827,36 @@
         {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
   }
 
- private:
-  void handleVlanPatch(const std::string &ifaceId, const nlohmann::json &input,
-                       const EthernetInterfaceData &eth_data,
-                       const std::shared_ptr<AsyncResp> &asyncResp) {
+  // TODO(kkowalsk) Find a suitable class/namespace for this
+  static void handleVlanPatch(const std::string &ifaceId,
+                              const nlohmann::json &input,
+                              const EthernetInterfaceData &eth_data,
+                              const std::string &pathPrefix,
+                              const std::shared_ptr<AsyncResp> &asyncResp) {
     if (!input.is_object()) {
       messages::addMessageToJson(
           asyncResp->res.json_value,
-          messages::propertyValueTypeError(input.dump(), "VLAN"), "/VLAN");
+          messages::propertyValueTypeError(input.dump(), "VLAN"), pathPrefix);
       return;
     }
 
+    const std::string pathStart = (pathPrefix == "/") ? "" : pathPrefix;
+    nlohmann::json &paramsJson =
+        (pathPrefix == "/")
+            ? asyncResp->res.json_value
+            : asyncResp->res.json_value[nlohmann::json_pointer<nlohmann::json>(
+                  pathPrefix)];
     bool inputVlanEnabled;
     uint64_t inputVlanId;
+
     json_util::Result inputVlanEnabledState = json_util::getBool(
         "VLANEnable", input, inputVlanEnabled,
         static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
-        asyncResp->res.json_value, std::string("/VLAN/VLANEnable"));
+        asyncResp->res.json_value, std::string(pathStart + "/VLANEnable"));
     json_util::Result inputVlanIdState = json_util::getUnsigned(
         "VLANId", input, inputVlanId,
         static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
-        asyncResp->res.json_value, std::string("/VLAN/VLANId"));
+        asyncResp->res.json_value, std::string(pathStart + "/VLANId"));
     bool inputInvalid = false;
 
     // Do not proceed if fields in VLAN object were of wrong type
@@ -857,31 +867,13 @@
 
     // Verify input
     if (eth_data.vlan_id == nullptr) {
-      // VLAN is currently disabled. User can only create/enable it. Change of
-      // VLANId is prohibited, and disable request (VLANEnabled == false) will
-      // not have any effect.
-      if (inputVlanEnabledState == json_util::Result::SUCCESS &&
-          inputVlanEnabled == true) {
-        // Creation requested, user should also provide ID for new VLAN
-        if (inputVlanIdState != json_util::Result::SUCCESS) {
-          messages::addMessageToJson(asyncResp->res.json_value,
-                                     messages::propertyMissing("VLANId"),
-                                     "/VLAN");
-          inputInvalid = true;
-        }
-      } else if (inputVlanIdState == json_util::Result::SUCCESS) {
-        // VLAN is disabled, but user requested modification. This is not valid.
-        messages::addMessageToJson(
-            asyncResp->res.json_value,
-            messages::actionParameterNotSupported("VLANId", "change VLAN Id"),
-            "/VLAN");
+      // This interface is not a VLAN. Cannot do anything with it
+      // TODO(kkowalsk) Change this message
+      messages::addMessageToJson(asyncResp->res.json_value,
+                                 messages::propertyMissing("VLANEnable"),
+                                 pathPrefix);
 
-        messages::addMessageToJson(asyncResp->res.json_value,
-                                   messages::propertyMissing("VLANEnable"),
-                                   "/VLAN");
-
-        inputInvalid = true;
-      }
+      inputInvalid = true;
     } else {
       // Load actual data into field values if they were not provided
       if (inputVlanEnabledState == json_util::Result::NOT_EXIST) {
@@ -898,45 +890,37 @@
       return;
     }
 
-    auto vlanEnabledAfterOperation =
-        [asyncResp](const boost::system::error_code ec) {
-          if (ec) {
-            messages::addMessageToJson(asyncResp->res.json_value,
-                                       messages::internalError(), "/VLAN");
-          } else {
-            asyncResp->res.json_value["VLAN"]["VLANEnable"] = true;
-          }
-        };
-
-    if (eth_data.vlan_id == nullptr) {
-      if (inputVlanEnabled == true) {
-        ethernet_provider.createVlan(ifaceId, inputVlanId,
-                                     std::move(vlanEnabledAfterOperation));
-        asyncResp->res.json_value["VLAN"]["VLANId"] = inputVlanId;
-      }
-    } else {
-      // VLAN is configured on the interface
-      if (inputVlanEnabled == true && inputVlanId != *eth_data.vlan_id) {
-        // Change VLAN Id
-        asyncResp->res.json_value["VLAN"]["VLANId"] = inputVlanId;
-        ethernet_provider.changeVlanId(ifaceId,
-                                       static_cast<uint32_t>(inputVlanId),
-                                       std::move(vlanEnabledAfterOperation));
-      } else if (inputVlanEnabled == false) {
-        // Disable VLAN
-        ethernet_provider.disableVlan(
-            ifaceId, [asyncResp](const boost::system::error_code ec) {
-              if (ec) {
-                messages::addMessageToJson(asyncResp->res.json_value,
-                                           messages::internalError(), "/VLAN");
-              } else {
-                asyncResp->res.json_value["VLAN"]["VLANEnable"] = false;
-              }
-            });
-      }
+    // VLAN is configured on the interface
+    if (inputVlanEnabled == true && inputVlanId != *eth_data.vlan_id) {
+      // Change VLAN Id
+      paramsJson["VLANId"] = inputVlanId;
+      OnDemandEthernetProvider::changeVlanId(
+          ifaceId, static_cast<uint32_t>(inputVlanId),
+          [&, asyncResp, pathPrefx{std::move(pathPrefix)} ](
+              const boost::system::error_code ec) {
+            if (ec) {
+              messages::addMessageToJson(asyncResp->res.json_value,
+                                         messages::internalError(), pathPrefix);
+            } else {
+              paramsJson["VLANEnable"] = true;
+            }
+          });
+    } else if (inputVlanEnabled == false) {
+      // Disable VLAN
+      OnDemandEthernetProvider::disableVlan(
+          ifaceId, [&, asyncResp, pathPrefx{std::move(pathPrefix)} ](
+                       const boost::system::error_code ec) {
+            if (ec) {
+              messages::addMessageToJson(asyncResp->res.json_value,
+                                         messages::internalError(), pathPrefix);
+            } else {
+              paramsJson["VLANEnable"] = false;
+            }
+          });
     }
   }
 
+ private:
   void handleHostnamePatch(const nlohmann::json &input,
                            const EthernetInterfaceData &eth_data,
                            const std::shared_ptr<AsyncResp> &asyncResp) {
@@ -1260,6 +1244,9 @@
             // ... otherwise return error
             // TODO(Pawel)consider distinguish between non existing object, and
             // other errors
+            messages::addMessageToErrorJson(
+                res.json_value,
+                messages::resourceNotFound("EthernetInterface", iface_id));
             res.result(boost::beast::http::status::not_found);
           }
           res.end();
@@ -1311,7 +1298,7 @@
           for (auto propertyIt = patchReq.begin(); propertyIt != patchReq.end();
                ++propertyIt) {
             if (propertyIt.key() == "VLAN") {
-              handleVlanPatch(iface_id, propertyIt.value(), eth_data,
+              handleVlanPatch(iface_id, propertyIt.value(), eth_data, "/VLAN",
                               asyncResp);
             } else if (propertyIt.key() == "HostName") {
               handleHostnamePatch(propertyIt.value(), eth_data, asyncResp);
@@ -1347,4 +1334,424 @@
   OnDemandEthernetProvider ethernet_provider;
 };
 
+class VlanNetworkInterfaceCollection;
+
+/**
+ * VlanNetworkInterface derived class for delivering VLANNetworkInterface Schema
+ */
+class VlanNetworkInterface : public Node {
+ public:
+  /*
+   * Default Constructor
+   */
+  template <typename CrowApp>
+  // TODO(Pawel) Remove line from below, where we assume that there is only one
+  // manager called openbmc This shall be generic, but requires to update
+  // GetSubroutes method
+  VlanNetworkInterface(CrowApp &app)
+      : Node(app,
+             "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/VLANs/"
+             "<str>",
+             std::string(), std::string()) {
+    Node::json["@odata.type"] =
+        "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
+    Node::json["@odata.context"] =
+        "/redfish/v1/$metadata#VLanNetworkInterface.VLanNetworkInterface";
+    Node::json["Name"] = "VLAN Network Interface";
+
+    entityPrivileges = {
+        {boost::beast::http::verb::get, {{"Login"}}},
+        {boost::beast::http::verb::head, {{"Login"}}},
+        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+  }
+
+ private:
+  nlohmann::json parseInterfaceData(
+      const std::string &parent_iface_id, const std::string &iface_id,
+      const EthernetInterfaceData &eth_data,
+      const std::vector<IPv4AddressData> &ipv4_data) {
+    // Copy JSON object to avoid race condition
+    nlohmann::json json_response(Node::json);
+
+    // Fill out obvious data...
+    json_response["Id"] = iface_id;
+    json_response["@odata.id"] =
+        "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + parent_iface_id +
+        "/VLANs/" + iface_id;
+
+    json_response["VLANEnable"] = true;
+    json_response["VLANId"] = *eth_data.vlan_id;
+
+    return json_response;
+  }
+
+  bool verifyNames(crow::response &res, const std::string &parent,
+                   const std::string &iface) {
+    if (!boost::starts_with(iface, parent + "_")) {
+      messages::addMessageToErrorJson(
+          res.json_value,
+          messages::resourceNotFound("VLAN Network Interface", iface));
+      res.result(boost::beast::http::status::bad_request);
+      res.end();
+
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  /**
+   * Functions triggers appropriate requests on DBus
+   */
+  void doGet(crow::response &res, const crow::request &req,
+             const std::vector<std::string> &params) override {
+    // TODO(Pawel) this shall be parametrized call (two params) to get
+    // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
+    // Check if there is required param, truly entering this shall be
+    // impossible.
+    if (params.size() != 2) {
+      res.result(boost::beast::http::status::internal_server_error);
+      res.end();
+      return;
+    }
+
+    const std::string &parent_iface_id = params[0];
+    const std::string &iface_id = params[1];
+
+    if (!verifyNames(res, parent_iface_id, iface_id)) {
+      return;
+    }
+
+    // Get single eth interface data, and call the below callback for JSON
+    // preparation
+    ethernet_provider.getEthernetIfaceData(
+        iface_id,
+        [&, parent_iface_id, iface_id](
+            const bool &success, const EthernetInterfaceData &eth_data,
+            const std::vector<IPv4AddressData> &ipv4_data) {
+          if (success && eth_data.vlan_id != nullptr) {
+            res.json_value = parseInterfaceData(parent_iface_id, iface_id,
+                                                eth_data, ipv4_data);
+          } else {
+            // ... otherwise return error
+            // TODO(Pawel)consider distinguish between non existing object,
+            // and
+            // other errors
+            res.result(boost::beast::http::status::not_found);
+          }
+          res.end();
+        });
+  }
+
+  void doPatch(crow::response &res, const crow::request &req,
+               const std::vector<std::string> &params) override {
+    if (params.size() != 2) {
+      res.result(boost::beast::http::status::internal_server_error);
+      res.end();
+      return;
+    }
+
+    const std::string &parent_iface_id = params[0];
+    const std::string &iface_id = params[1];
+
+    if (!verifyNames(res, parent_iface_id, iface_id)) {
+      return;
+    }
+
+    nlohmann::json patchReq;
+
+    if (!json_util::processJsonFromRequest(res, req, patchReq)) {
+      return;
+    }
+
+    // Get single eth interface data, and call the below callback for JSON
+    // preparation
+    ethernet_provider.getEthernetIfaceData(
+        iface_id,
+        [&, parent_iface_id, iface_id, patchReq = std::move(patchReq) ](
+            const bool &success, const EthernetInterfaceData &eth_data,
+            const std::vector<IPv4AddressData> &ipv4_data) {
+          if (!success) {
+            // ... otherwise return error
+            // TODO(Pawel)consider distinguish between non existing object,
+            // and
+            // other errors
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+
+            return;
+          }
+
+          res.json_value = parseInterfaceData(parent_iface_id, iface_id,
+                                              eth_data, ipv4_data);
+
+          std::shared_ptr<AsyncResp> asyncResp =
+              std::make_shared<AsyncResp>(res);
+
+          for (auto propertyIt = patchReq.begin(); propertyIt != patchReq.end();
+               ++propertyIt) {
+            if (propertyIt.key() != "VLANEnable" &&
+                propertyIt.key() != "VLANId") {
+              auto fieldInJsonIt = res.json_value.find(propertyIt.key());
+
+              if (fieldInJsonIt == res.json_value.end()) {
+                // Field not in scope of defined fields
+                messages::addMessageToJsonRoot(
+                    res.json_value,
+                    messages::propertyUnknown(propertyIt.key()));
+              } else if (*fieldInJsonIt != *propertyIt) {
+                // User attempted to modify non-writable field
+                messages::addMessageToJsonRoot(
+                    res.json_value,
+                    messages::propertyNotWritable(propertyIt.key()));
+              }
+            }
+          }
+
+          EthernetInterface::handleVlanPatch(iface_id, patchReq, eth_data, "/",
+                                             asyncResp);
+        });
+  }
+
+  void doDelete(crow::response &res, const crow::request &req,
+                const std::vector<std::string> &params) override {
+    if (params.size() != 2) {
+      res.result(boost::beast::http::status::internal_server_error);
+      res.end();
+      return;
+    }
+
+    const std::string &parent_iface_id = params[0];
+    const std::string &iface_id = params[1];
+
+    if (!verifyNames(res, parent_iface_id, iface_id)) {
+      return;
+    }
+
+    // Get single eth interface data, and call the below callback for JSON
+    // preparation
+    ethernet_provider.getEthernetIfaceData(
+        iface_id,
+        [&, parent_iface_id, iface_id](
+            const bool &success, const EthernetInterfaceData &eth_data,
+            const std::vector<IPv4AddressData> &ipv4_data) {
+          if (success && eth_data.vlan_id != nullptr) {
+            res.json_value = parseInterfaceData(parent_iface_id, iface_id,
+                                                eth_data, ipv4_data);
+
+            // Disable VLAN
+            OnDemandEthernetProvider::disableVlan(
+                iface_id, [&](const boost::system::error_code ec) {
+                  if (ec) {
+                    res.json_value = nlohmann::json::object();
+                    messages::addMessageToErrorJson(res.json_value,
+                                                    messages::internalError());
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                  }
+                  res.end();
+                });
+          } else {
+            // ... otherwise return error
+            // TODO(Pawel)consider distinguish between non existing object,
+            // and
+            // other errors
+
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+          }
+        });
+  }
+
+  /**
+   * This allows VlanNetworkInterfaceCollection to reuse this class' doGet
+   * method, to maintain consistency of returned data, as Collection's doPost
+   * should return data for created member which should match member's doGet
+   * result in 100%.
+   */
+  friend VlanNetworkInterfaceCollection;
+
+  // Ethernet Provider object
+  // TODO(Pawel) consider move it to singleton
+  OnDemandEthernetProvider ethernet_provider;
+};
+
+/**
+ * VlanNetworkInterfaceCollection derived class for delivering
+ * VLANNetworkInterface Collection Schema
+ */
+class VlanNetworkInterfaceCollection : public Node {
+ public:
+  template <typename CrowApp>
+  // TODO(Pawel) Remove line from below, where we assume that there is only one
+  // manager called openbmc This shall be generic, but requires to update
+  // GetSubroutes method
+  VlanNetworkInterfaceCollection(CrowApp &app)
+      : Node(app,
+             "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/VLANs/",
+             std::string()),
+        memberVlan(app) {
+    Node::json["@odata.type"] =
+        "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
+    Node::json["@odata.context"] =
+        "/redfish/v1/$metadata"
+        "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
+    Node::json["Name"] = "VLAN Network Interface Collection";
+
+    entityPrivileges = {
+        {boost::beast::http::verb::get, {{"Login"}}},
+        {boost::beast::http::verb::head, {{"Login"}}},
+        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+  }
+
+ private:
+  /**
+   * Functions triggers appropriate requests on DBus
+   */
+  void doGet(crow::response &res, const crow::request &req,
+             const std::vector<std::string> &params) override {
+    if (params.size() != 1) {
+      // This means there is a problem with the router
+      res.result(boost::beast::http::status::internal_server_error);
+      res.end();
+
+      return;
+    }
+
+    // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces for
+    // any Manager, not only hardcoded 'openbmc'.
+    std::string manager_id = "openbmc";
+    std::string rootInterfaceName = params[0];
+
+    // Get eth interface list, and call the below callback for JSON preparation
+    ethernet_provider.getEthernetIfaceList([
+          &, manager_id{std::move(manager_id)},
+          rootInterfaceName{std::move(rootInterfaceName)}
+    ](const bool &success, const std::vector<std::string> &iface_list) {
+      if (success) {
+        bool rootInterfaceFound = false;
+        nlohmann::json iface_array = nlohmann::json::array();
+
+        for (const std::string &iface_item : iface_list) {
+          if (iface_item == rootInterfaceName) {
+            rootInterfaceFound = true;
+          } else if (boost::starts_with(iface_item, rootInterfaceName + "_")) {
+            iface_array.push_back(
+                {{"@odata.id", "/redfish/v1/Managers/" + manager_id +
+                                   "/EthernetInterfaces/" + rootInterfaceName +
+                                   "/VLANs/" + iface_item}});
+          }
+        }
+
+        if (rootInterfaceFound) {
+          Node::json["Members"] = iface_array;
+          Node::json["Members@odata.count"] = iface_array.size();
+          Node::json["@odata.id"] = "/redfish/v1/Managers/" + manager_id +
+                                    "/EthernetInterfaces/" + rootInterfaceName +
+                                    "/VLANs";
+          res.json_value = Node::json;
+        } else {
+          messages::addMessageToErrorJson(
+              res.json_value, messages::resourceNotFound("EthernetInterface",
+                                                         rootInterfaceName));
+          res.result(boost::beast::http::status::not_found);
+          res.end();
+        }
+      } else {
+        // No success, best what we can do is return INTERNALL ERROR
+        res.result(boost::beast::http::status::internal_server_error);
+      }
+      res.end();
+    });
+  }
+
+  void doPost(crow::response &res, const crow::request &req,
+              const std::vector<std::string> &params) override {
+    if (params.size() != 1) {
+      // This means there is a problem with the router
+      res.result(boost::beast::http::status::internal_server_error);
+      res.end();
+      return;
+    }
+
+    nlohmann::json postReq;
+
+    if (!json_util::processJsonFromRequest(res, req, postReq)) {
+      return;
+    }
+
+    // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces for
+    // any Manager, not only hardcoded 'openbmc'.
+    std::string manager_id = "openbmc";
+    std::string rootInterfaceName = params[0];
+    uint64_t vlanId;
+    bool errorDetected;
+
+    if (json_util::getUnsigned(
+            "VLANId", postReq, vlanId,
+            static_cast<uint8_t>(json_util::MessageSetting::MISSING) |
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+            res.json_value, "/VLANId") != json_util::Result::SUCCESS) {
+      res.end();
+      return;
+    }
+
+    // Get eth interface list, and call the below callback for JSON preparation
+    ethernet_provider.getEthernetIfaceList([
+          &, manager_id{std::move(manager_id)},
+          rootInterfaceName{std::move(rootInterfaceName)}
+    ](const bool &success, const std::vector<std::string> &iface_list) {
+      if (success) {
+        bool rootInterfaceFound = false;
+
+        for (const std::string &iface_item : iface_list) {
+          if (iface_item == rootInterfaceName) {
+            rootInterfaceFound = true;
+            break;
+          }
+        }
+
+        if (rootInterfaceFound) {
+          ethernet_provider.createVlan(
+              rootInterfaceName, vlanId,
+              [&, vlanId, rootInterfaceName,
+               req{std::move(req)} ](const boost::system::error_code ec) {
+                if (ec) {
+                  messages::addMessageToErrorJson(res.json_value,
+                                                  messages::internalError());
+                  res.end();
+                } else {
+                  memberVlan.doGet(
+                      res, req,
+                      {rootInterfaceName,
+                       rootInterfaceName + "_" + std::to_string(vlanId)});
+                }
+              });
+        } else {
+          messages::addMessageToErrorJson(
+              res.json_value, messages::resourceNotFound("EthernetInterface",
+                                                         rootInterfaceName));
+          res.result(boost::beast::http::status::not_found);
+          res.end();
+        }
+      } else {
+        // No success, best what we can do is return INTERNALL ERROR
+        res.result(boost::beast::http::status::internal_server_error);
+        res.end();
+      }
+    });
+  }
+
+  // Ethernet Provider object
+  // TODO(Pawel) consider move it to singleton
+  OnDemandEthernetProvider ethernet_provider;
+  VlanNetworkInterface memberVlan;
+};
+
 }  // namespace redfish
