diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 8a8b656..8c3885f 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -17,6 +17,7 @@
 
 #include "../lib/account_service.hpp"
 #include "../lib/chassis.hpp"
+#include "../lib/cpudimm.hpp"
 #include "../lib/ethernet.hpp"
 #include "../lib/log_services.hpp"
 #include "../lib/managers.hpp"
@@ -85,6 +86,11 @@
 #endif // BMCWEB_ENABLE_REDFISH_RAW_PECI
 #endif // BMCWEB_ENABLE_REDFISH_CPU_LOG
 
+        nodes.emplace_back(std::make_unique<ProcessorCollection>(app));
+        nodes.emplace_back(std::make_unique<Processor>(app));
+        nodes.emplace_back(std::make_unique<MemoryCollection>(app));
+        nodes.emplace_back(std::make_unique<Memory>(app));
+
         nodes.emplace_back(std::make_unique<SystemsCollection>(app));
         nodes.emplace_back(std::make_unique<Systems>(app));
         nodes.emplace_back(std::make_unique<SystemActionsReset>(app));
diff --git a/redfish-core/lib/cpudimm.hpp b/redfish-core/lib/cpudimm.hpp
new file mode 100644
index 0000000..120b2b5
--- /dev/null
+++ b/redfish-core/lib/cpudimm.hpp
@@ -0,0 +1,513 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed 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.
+*/
+#pragma once
+
+#include <boost/container/flat_map.hpp>
+#include <node.hpp>
+#include <utils/json_utils.hpp>
+
+namespace redfish
+{
+
+void getResourceList(std::shared_ptr<AsyncResp> aResp, const std::string &name,
+                     const std::string &subclass,
+                     const std::string &collectionName)
+{
+    BMCWEB_LOG_DEBUG << "Get available system cpu/mem resources.";
+    crow::connections::systemBus->async_method_call(
+        [name, subclass, aResp{std::move(aResp)}](
+            const boost::system::error_code ec,
+            const boost::container::flat_map<
+                std::string, boost::container::flat_map<
+                                 std::string, std::vector<std::string>>>
+                &subtree) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "DBUS response error";
+                messages::internalError(aResp->res);
+                return;
+            }
+            nlohmann::json &members = aResp->res.jsonValue["Members"];
+            members = nlohmann::json::array();
+
+            for (const auto &object : subtree)
+            {
+                auto iter = object.first.rfind("/");
+                if ((iter != std::string::npos) && (iter < object.first.size()))
+                {
+                    members.push_back(
+                        {{"@odata.id", "/redfish/v1/Systems/" + name + "/" +
+                                           subclass + "/" +
+                                           object.first.substr(iter + 1)}});
+                }
+            }
+            aResp->res.jsonValue["Members@odata.count"] = members.size();
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+        "/xyz/openbmc_project/inventory", int32_t(0),
+        std::array<const char *, 1>{collectionName.c_str()});
+}
+
+void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
+                         const std::string &name, const std::string &cpuId,
+                         const std::string &service, const std::string &objPath)
+{
+    BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
+    crow::connections::systemBus->async_method_call(
+        [name, cpuId, aResp{std::move(aResp)}](
+            const boost::system::error_code ec,
+            const boost::container::flat_map<
+                std::string,
+                sdbusplus::message::variant<std::string, uint32_t, uint16_t>>
+                &properties) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "DBUS response error";
+                messages::internalError(aResp->res);
+
+                return;
+            }
+            aResp->res.jsonValue["Id"] = cpuId;
+            aResp->res.jsonValue["Name"] = "Processor";
+            const auto coresCountProperty =
+                properties.find("ProcessorCoreCount");
+            if (coresCountProperty == properties.end())
+            {
+                // Important property not in result
+                messages::internalError(aResp->res);
+                return;
+            }
+            const uint16_t *coresCount =
+                mapbox::getPtr<const uint16_t>(coresCountProperty->second);
+            if (coresCount == nullptr)
+            {
+                // Important property not in desired type
+                messages::internalError(aResp->res);
+                return;
+            }
+            if (*coresCount == 0)
+            {
+                // Slot is not populated, set status end return
+                aResp->res.jsonValue["Status"]["State"] = "Absent";
+                aResp->res.jsonValue["Status"]["Health"] = "OK";
+                // HTTP Code will be set up automatically, just return
+                return;
+            }
+
+            aResp->res.jsonValue["TotalCores"] = *coresCount;
+            aResp->res.jsonValue["Status"]["State"] = "Enabled";
+            aResp->res.jsonValue["Status"]["Health"] = "OK";
+
+            for (const auto &property : properties)
+            {
+                if (property.first == "ProcessorType")
+                {
+                    aResp->res.jsonValue["Name"] = property.second;
+                }
+                else if (property.first == "ProcessorManufacturer")
+                {
+                    aResp->res.jsonValue["Manufacturer"] = property.second;
+                    const std::string *value =
+                        mapbox::getPtr<const std::string>(property.second);
+                    if (value != nullptr)
+                    {
+                        // Otherwise would be unexpected.
+                        if (value->find("Intel") != std::string::npos)
+                        {
+                            aResp->res.jsonValue["ProcessorArchitecture"] =
+                                "x86";
+                            aResp->res.jsonValue["InstructionSet"] = "x86-64";
+                        }
+                    }
+                }
+                else if (property.first == "ProcessorMaxSpeed")
+                {
+                    aResp->res.jsonValue["MaxSpeedMHz"] = property.second;
+                }
+                else if (property.first == "ProcessorThreadCount")
+                {
+                    aResp->res.jsonValue["TotalThreads"] = property.second;
+                }
+                else if (property.first == "ProcessorVersion")
+                {
+                    aResp->res.jsonValue["Model"] = property.second;
+                }
+            }
+        },
+        service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
+}
+
+void getCpuData(std::shared_ptr<AsyncResp> aResp, const std::string &name,
+                const std::string &cpuId)
+{
+    BMCWEB_LOG_DEBUG << "Get available system cpu resources.";
+    crow::connections::systemBus->async_method_call(
+        [name, cpuId, aResp{std::move(aResp)}](
+            const boost::system::error_code ec,
+            const boost::container::flat_map<
+                std::string, boost::container::flat_map<
+                                 std::string, std::vector<std::string>>>
+                &subtree) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "DBUS response error";
+                messages::internalError(aResp->res);
+                return;
+            }
+            for (const auto &object : subtree)
+            {
+                if (boost::ends_with(object.first, cpuId))
+                {
+                    for (const auto &service : object.second)
+                    {
+                        getCpuDataByService(aResp, name, cpuId, service.first,
+                                            object.first);
+                        return;
+                    }
+                }
+            }
+            // Object not found
+            messages::resourceNotFound(aResp->res, "Processor", cpuId);
+            return;
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+        "/xyz/openbmc_project/inventory", int32_t(0),
+        std::array<const char *, 1>{"xyz.openbmc_project.Inventory.Item.Cpu"});
+};
+
+void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
+                          const std::string &name, const std::string &dimmId,
+                          const std::string &service,
+                          const std::string &objPath)
+{
+    BMCWEB_LOG_DEBUG << "Get available system components.";
+    crow::connections::systemBus->async_method_call(
+        [name, dimmId, aResp{std::move(aResp)}](
+            const boost::system::error_code ec,
+            const boost::container::flat_map<
+                std::string,
+                sdbusplus::message::variant<std::string, uint32_t, uint16_t>>
+                &properties) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "DBUS response error";
+                messages::internalError(aResp->res);
+
+                return;
+            }
+            aResp->res.jsonValue["Id"] = dimmId;
+            aResp->res.jsonValue["Name"] = "DIMM Slot";
+
+            const auto memorySizeProperty = properties.find("MemorySizeInKB");
+            if (memorySizeProperty == properties.end())
+            {
+                // Important property not in result
+                messages::internalError(aResp->res);
+
+                return;
+            }
+            const uint32_t *memorySize =
+                mapbox::getPtr<const uint32_t>(memorySizeProperty->second);
+            if (memorySize == nullptr)
+            {
+                // Important property not in desired type
+                messages::internalError(aResp->res);
+
+                return;
+            }
+            if (*memorySize == 0)
+            {
+                // Slot is not populated, set status end return
+                aResp->res.jsonValue["Status"]["State"] = "Absent";
+                aResp->res.jsonValue["Status"]["Health"] = "OK";
+                // HTTP Code will be set up automatically, just return
+                return;
+            }
+            aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
+            aResp->res.jsonValue["Status"]["State"] = "Enabled";
+            aResp->res.jsonValue["Status"]["Health"] = "OK";
+
+            for (const auto &property : properties)
+            {
+                if (property.first == "MemoryDataWidth")
+                {
+                    aResp->res.jsonValue["DataWidthBits"] = property.second;
+                }
+                else if (property.first == "MemoryType")
+                {
+                    const auto *value =
+                        mapbox::getPtr<const std::string>(property.second);
+                    if (value != nullptr)
+                    {
+                        aResp->res.jsonValue["MemoryDeviceType"] = *value;
+                        if (boost::starts_with(*value, "DDR"))
+                        {
+                            aResp->res.jsonValue["MemoryType"] = "DRAM";
+                        }
+                    }
+                }
+            }
+        },
+        service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
+}
+
+void getDimmData(std::shared_ptr<AsyncResp> aResp, const std::string &name,
+                 const std::string &dimmId)
+{
+    BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
+    crow::connections::systemBus->async_method_call(
+        [name, dimmId, aResp{std::move(aResp)}](
+            const boost::system::error_code ec,
+            const boost::container::flat_map<
+                std::string, boost::container::flat_map<
+                                 std::string, std::vector<std::string>>>
+                &subtree) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "DBUS response error";
+                messages::internalError(aResp->res);
+
+                return;
+            }
+            for (const auto &object : subtree)
+            {
+                if (boost::ends_with(object.first, dimmId))
+                {
+                    for (const auto &service : object.second)
+                    {
+                        getDimmDataByService(aResp, name, dimmId, service.first,
+                                             object.first);
+                        return;
+                    }
+                }
+            }
+            // Object not found
+            messages::resourceNotFound(aResp->res, "Memory", dimmId);
+            return;
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+        "/xyz/openbmc_project/inventory", int32_t(0),
+        std::array<const char *, 1>{"xyz.openbmc_project.Inventory.Item.Dimm"});
+};
+
+class ProcessorCollection : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    ProcessorCollection(CrowApp &app) :
+        Node(app, "/redfish/v1/Systems/<str>/Processors/", std::string())
+    {
+
+        Node::json["@odata.type"] = "#ProcessorCollection.ProcessorCollection";
+        Node::json["Name"] = "Processor Collection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ProcessorCollection.ProcessorCollection";
+        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
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible
+        if (params.size() != 1)
+        {
+            messages::internalError(res);
+            res.end();
+            return;
+        }
+        const std::string &name = params[0];
+
+        res.jsonValue = Node::json;
+        res.jsonValue["@odata.id"] =
+            "/redfish/v1/Systems/" + name + "/Processors/";
+        auto asyncResp = std::make_shared<AsyncResp>(res);
+
+        getResourceList(asyncResp, name, "Processors",
+                        "xyz.openbmc_project.Inventory.Item.Cpu");
+    }
+};
+
+class Processor : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    Processor(CrowApp &app) :
+        Node(app, "/redfish/v1/Systems/<str>/Processors/<str>/", std::string(),
+             std::string())
+    {
+
+        Node::json["@odata.type"] = "#Processor.v1_1_0.Processor";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#Processor.Processor";
+        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
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible
+        if (params.size() != 2)
+        {
+            messages::internalError(res);
+
+            res.end();
+            return;
+        }
+        const std::string &name = params[0];
+        const std::string &cpuId = params[1];
+
+        res.jsonValue = Node::json;
+        res.jsonValue["@odata.id"] =
+            "/redfish/v1/Systems/" + name + "/Processors/" + cpuId;
+
+        auto asyncResp = std::make_shared<AsyncResp>(res);
+
+        getCpuData(asyncResp, name, cpuId);
+    }
+};
+
+class MemoryCollection : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    MemoryCollection(CrowApp &app) :
+        Node(app, "/redfish/v1/Systems/<str>/Memory/", std::string())
+    {
+
+        Node::json["@odata.type"] = "#MemoryCollection.MemoryCollection";
+        Node::json["Name"] = "Memory Module Collection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#MemoryCollection.MemoryCollection";
+        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
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible
+        if (params.size() != 1)
+        {
+            messages::internalError(res);
+
+            res.end();
+            return;
+        }
+        const std::string &name = params[0];
+
+        res.jsonValue = Node::json;
+        res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name + "/Memory/";
+        auto asyncResp = std::make_shared<AsyncResp>(res);
+
+        getResourceList(asyncResp, name, "Memory",
+                        "xyz.openbmc_project.Inventory.Item.Dimm");
+    }
+};
+
+class Memory : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    Memory(CrowApp &app) :
+        Node(app, "/redfish/v1/Systems/<str>/Memory/<str>/", std::string(),
+             std::string())
+    {
+
+        Node::json["@odata.type"] = "#Memory.v1_2_0.Memory";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Memory.Memory";
+        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
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible
+        if (params.size() != 2)
+        {
+            messages::internalError(res);
+            res.end();
+            return;
+        }
+        const std::string &name = params[0];
+        const std::string &dimmId = params[1];
+
+        res.jsonValue = Node::json;
+        res.jsonValue["@odata.id"] =
+            "/redfish/v1/Systems/" + name + "/Memory/" + dimmId;
+        auto asyncResp = std::make_shared<AsyncResp>(res);
+
+        getDimmData(asyncResp, name, dimmId);
+    }
+};
+
+} // namespace redfish
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 027c276..4ab4eb9 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -701,6 +701,10 @@
         res.jsonValue = Node::json;
         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
 
+        res.jsonValue["Processors"] = {
+            {"@odata.id", "/redfish/v1/Systems/" + name + "/Processors"}};
+        res.jsonValue["Memory"] = {
+            {"@odata.id", "/redfish/v1/Systems/" + name + "/Memory"}};
         // TODO Need to support ForceRestart.
         res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
             {"target",
