diff --git a/wait-vpd-parser/src/prime_inventory.cpp b/wait-vpd-parser/src/prime_inventory.cpp
index 79125fe..b09b635 100644
--- a/wait-vpd-parser/src/prime_inventory.cpp
+++ b/wait-vpd-parser/src/prime_inventory.cpp
@@ -8,6 +8,7 @@
 #include "utility/vpd_specific_utility.hpp"
 
 #include <string>
+#include <vector>
 
 PrimeInventory::PrimeInventory()
 {
@@ -32,6 +33,8 @@
                 "Mandatory tag(s) missing from JSON file [" +
                 std::string(INVENTORY_JSON_SYM_LINK) + "]");
         }
+
+        m_logger = vpd::Logger::getLoggerInstance();
     }
     catch (const std::exception& l_ex)
     {
@@ -47,7 +50,42 @@
 
 bool PrimeInventory::isPrimingRequired() const noexcept
 {
-    // ToDo: Check if priming is required.
+    try
+    {
+        // get all object paths under PIM
+        const auto l_objectPaths = vpd::dbusUtility::GetSubTreePaths(
+            vpd::constants::systemInvPath, 0,
+            std::vector<std::string>{vpd::constants::vpdCollectionInterface});
+
+        const nlohmann::json& l_listOfFrus =
+            m_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+        size_t l_invPathCount = 0;
+
+        for (const auto& l_itemFRUS : l_listOfFrus.items())
+        {
+            for (const auto& l_Fru : l_itemFRUS.value())
+            {
+                if (l_Fru.contains("ccin") || (l_Fru.contains("noprime") &&
+                                               l_Fru.value("noprime", false)))
+                {
+                    continue;
+                }
+
+                l_invPathCount += 1;
+            }
+        }
+        return ((l_objectPaths.size() >= l_invPathCount) ? false : true);
+    }
+    catch (const std::exception& l_ex)
+    {
+        m_logger->logMessage(
+            "Error while checking is priming required or not, error: " +
+            std::string(l_ex.what()));
+    }
+
+    // In case of any error, perform priming, as it's unclear whether priming is
+    // required.
     return true;
 }
 
@@ -55,45 +93,353 @@
 {
     try
     {
-        /*ToDo:
-      * Check if priming is required.
-      * Traverse the system config JSON &
-      prime all the FRU paths which qualifies for priming.
-      */
+        if (m_sysCfgJsonObj.empty())
+        {
+            return;
+        }
+
+        const nlohmann::json& l_listOfFrus =
+            m_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+        vpd::types::ObjectMap l_objectInterfaceMap;
+        for (const auto& l_itemFRUS : l_listOfFrus.items())
+        {
+            const std::string& l_vpdFilePath = l_itemFRUS.key();
+
+            if (l_vpdFilePath == SYSTEM_VPD_FILE_PATH)
+            {
+                continue;
+            }
+
+            // Prime the inventry for FRUs
+            for (const auto& l_Fru : m_sysCfgJsonObj["frus"][l_vpdFilePath])
+            {
+                if (!primeInventory(l_objectInterfaceMap, l_Fru))
+                {
+                    m_logger->logMessage(
+                        "Priming of inventory failed for FRU " +
+                        std::string(l_Fru["inventoryPath"]));
+                }
+            }
+        }
+
+        // Notify PIM
+        if (!l_objectInterfaceMap.empty())
+        {
+            if (!vpd::dbusUtility::callPIM(move(l_objectInterfaceMap)))
+            {
+                m_logger->logMessage(
+                    "Call to PIM failed while priming inventory");
+            }
+        }
+        else
+        {
+            m_logger->logMessage("Priming inventory failed");
+        }
     }
     catch (const std::exception& l_ex)
     {
-        // ToDo: log an error
+        m_logger->logMessage("Prime system inventory failed, reason: " +
+                             std::string(l_ex.what()));
     }
 }
 
 bool PrimeInventory::primeInventory(
-    [[maybe_unused]] const std::string& i_vpdFilePath) const noexcept
+    vpd::types::ObjectMap& o_objectInterfaceMap,
+    const nlohmann::json& i_fruJsonObj) const noexcept
 {
-    // ToDo: Travers system config JSON & prime inventory objects found under
-    // the EEPROM.
+    if (i_fruJsonObj.empty())
+    {
+        m_logger->logMessage("Empty FRU JSON given");
+        return false;
+    }
+
+    vpd::types::InterfaceMap l_interfaces;
+    sdbusplus::message::object_path l_fruObjectPath(
+        i_fruJsonObj["inventoryPath"]);
+
+    if (i_fruJsonObj.contains("ccin"))
+    {
+        return true;
+    }
+
+    if (i_fruJsonObj.contains("noprime") &&
+        i_fruJsonObj.value("noprime", false))
+    {
+        return true;
+    }
+
+    // Reset data under PIM for this FRU only if the FRU is not synthesized
+    // and we handle it's Present property.
+    if (isPresentPropertyHandlingRequired(i_fruJsonObj))
+    {
+        // Clear data under PIM if already exists.
+        vpd::vpdSpecificUtility::resetDataUnderPIM(
+            std::string(i_fruJsonObj["inventoryPath"]), l_interfaces);
+    }
+
+    // Add extra interfaces mentioned in the Json config file
+    if (i_fruJsonObj.contains("extraInterfaces"))
+    {
+        populateInterfaces(i_fruJsonObj["extraInterfaces"], l_interfaces,
+                           std::monostate{});
+    }
+
+    vpd::types::PropertyMap l_propertyValueMap;
+
+    // Update Present property for this FRU only if we handle Present
+    // property for the FRU.
+    if (isPresentPropertyHandlingRequired(i_fruJsonObj))
+    {
+        l_propertyValueMap.emplace("Present", false);
+
+        // TODO: Present based on file will be taken care in future.
+        // By default present is set to false for FRU at the time of
+        // priming. Once collection goes through, it will be set to true in
+        // that flow.
+        /*if (std::filesystem::exists(i_vpdFilePath))
+        {
+            l_propertyValueMap["Present"] = true;
+        }*/
+    }
+
+    vpd::vpdSpecificUtility::insertOrMerge(
+        l_interfaces, "xyz.openbmc_project.Inventory.Item",
+        move(l_propertyValueMap));
+
+    if (i_fruJsonObj.value("inherit", true) &&
+        m_sysCfgJsonObj.contains("commonInterfaces"))
+    {
+        populateInterfaces(m_sysCfgJsonObj["commonInterfaces"], l_interfaces,
+                           std::monostate{});
+    }
+
+    processFunctionalProperty(i_fruJsonObj["inventoryPath"], l_interfaces);
+    processEnabledProperty(i_fruJsonObj["inventoryPath"], l_interfaces);
+
+    // Emplace the default state of FRU VPD collection
+    vpd::types::PropertyMap l_fruCollectionProperty = {
+        {"Status", vpd::constants::vpdCollectionNotStarted}};
+
+    vpd::vpdSpecificUtility::insertOrMerge(
+        l_interfaces, vpd::constants::vpdCollectionInterface,
+        std::move(l_fruCollectionProperty));
+
+    o_objectInterfaceMap.emplace(std::move(l_fruObjectPath),
+                                 std::move(l_interfaces));
+
     return true;
 }
 
 void PrimeInventory::populateInterfaces(
-    [[maybe_unused]] const nlohmann::json& i_interfaceJson,
-    [[maybe_unused]] vpd::types::InterfaceMap& io_interfaceMap,
-    [[maybe_unused]] const vpd::types::VPDMapVariant& i_parsedVpdMap)
-    const noexcept
+    const nlohmann::json& i_interfaceJson,
+    vpd::types::InterfaceMap& io_interfaceMap,
+    const vpd::types::VPDMapVariant& i_parsedVpdMap) const noexcept
 {
-    // ToDo: Populate interfaces needs to be published on Dbus.
+    for (const auto& l_interfacesPropPair : i_interfaceJson.items())
+    {
+        const std::string& l_interface = l_interfacesPropPair.key();
+        vpd::types::PropertyMap l_propertyMap;
+
+        for (const auto& l_propValuePair : l_interfacesPropPair.value().items())
+        {
+            const std::string l_property = l_propValuePair.key();
+
+            if (l_propValuePair.value().is_boolean())
+            {
+                l_propertyMap.emplace(l_property,
+                                      l_propValuePair.value().get<bool>());
+            }
+            else if (l_propValuePair.value().is_string())
+            {
+                if (l_property.compare("LocationCode") == 0 &&
+                    l_interface.compare("com.ibm.ipzvpd.Location") == 0)
+                {
+                    std::string l_value =
+                        vpd::vpdSpecificUtility::getExpandedLocationCode(
+                            l_propValuePair.value().get<std::string>(),
+                            i_parsedVpdMap);
+                    l_propertyMap.emplace(l_property, l_value);
+
+                    auto l_locCodeProperty = l_propertyMap;
+                    vpd::vpdSpecificUtility::insertOrMerge(
+                        io_interfaceMap,
+                        std::string(vpd::constants::xyzLocationCodeInf),
+                        move(l_locCodeProperty));
+                }
+                else
+                {
+                    l_propertyMap.emplace(
+                        l_property, l_propValuePair.value().get<std::string>());
+                }
+            }
+            else if (l_propValuePair.value().is_array())
+            {
+                try
+                {
+                    l_propertyMap.emplace(l_property,
+                                          l_propValuePair.value()
+                                              .get<vpd::types::BinaryVector>());
+                }
+                catch (const nlohmann::detail::type_error& e)
+                {
+                    std::cerr << "Type exception: " << e.what() << "\n";
+                }
+            }
+            else if (l_propValuePair.value().is_number())
+            {
+                // For now assume the value is a size_t.  In the future it would
+                // be nice to come up with a way to get the type from the JSON.
+                l_propertyMap.emplace(l_property,
+                                      l_propValuePair.value().get<size_t>());
+            }
+            else if (l_propValuePair.value().is_object())
+            {
+                const std::string& l_record =
+                    l_propValuePair.value().value("recordName", "");
+                const std::string& l_keyword =
+                    l_propValuePair.value().value("keywordName", "");
+                const std::string& l_encoding =
+                    l_propValuePair.value().value("encoding", "");
+
+                if (auto l_ipzVpdMap =
+                        std::get_if<vpd::types::IPZVpdMap>(&i_parsedVpdMap))
+                {
+                    if (!l_record.empty() && !l_keyword.empty() &&
+                        (*l_ipzVpdMap).count(l_record) &&
+                        (*l_ipzVpdMap).at(l_record).count(l_keyword))
+                    {
+                        auto l_encoded = vpd::vpdSpecificUtility::encodeKeyword(
+                            ((*l_ipzVpdMap).at(l_record).at(l_keyword)),
+                            l_encoding);
+                        l_propertyMap.emplace(l_property, l_encoded);
+                    }
+                }
+                else if (auto l_kwdVpdMap =
+                             std::get_if<vpd::types::KeywordVpdMap>(
+                                 &i_parsedVpdMap))
+                {
+                    if (!l_keyword.empty() && (*l_kwdVpdMap).count(l_keyword))
+                    {
+                        if (auto l_kwValue =
+                                std::get_if<vpd::types::BinaryVector>(
+                                    &(*l_kwdVpdMap).at(l_keyword)))
+                        {
+                            auto l_encodedValue =
+                                vpd::vpdSpecificUtility::encodeKeyword(
+                                    std::string((*l_kwValue).begin(),
+                                                (*l_kwValue).end()),
+                                    l_encoding);
+
+                            l_propertyMap.emplace(l_property, l_encodedValue);
+                        }
+                        else if (auto l_kwValue = std::get_if<std::string>(
+                                     &(*l_kwdVpdMap).at(l_keyword)))
+                        {
+                            auto l_encodedValue =
+                                vpd::vpdSpecificUtility::encodeKeyword(
+                                    std::string((*l_kwValue).begin(),
+                                                (*l_kwValue).end()),
+                                    l_encoding);
+
+                            l_propertyMap.emplace(l_property, l_encodedValue);
+                        }
+                        else if (auto l_uintValue = std::get_if<size_t>(
+                                     &(*l_kwdVpdMap).at(l_keyword)))
+                        {
+                            l_propertyMap.emplace(l_property, *l_uintValue);
+                        }
+                        else
+                        {
+                            m_logger->logMessage(
+                                "Unknown keyword found, Keywrod = " +
+                                l_keyword);
+                        }
+                    }
+                }
+            }
+        }
+        vpd::vpdSpecificUtility::insertOrMerge(io_interfaceMap, l_interface,
+                                               move(l_propertyMap));
+    }
 }
 
 void PrimeInventory::processFunctionalProperty(
-    [[maybe_unused]] const std::string& i_inventoryObjPath,
-    [[maybe_unused]] vpd::types::InterfaceMap& io_interfaces) const noexcept
+    const std::string& i_inventoryObjPath,
+    vpd::types::InterfaceMap& io_interfaces) const noexcept
 {
-    // ToDo: Populate interface to publish Functional property on Dbus.
+    if (!vpd::dbusUtility::isChassisPowerOn())
+    {
+        std::vector<std::string> l_operationalStatusInf{
+            vpd::constants::operationalStatusInf};
+
+        auto l_mapperObjectMap = vpd::dbusUtility::getObjectMap(
+            i_inventoryObjPath, l_operationalStatusInf);
+
+        // If the object has been found. Check if it is under PIM.
+        if (l_mapperObjectMap.size() != 0)
+        {
+            for (const auto& [l_serviceName, l_interfaceLsit] :
+                 l_mapperObjectMap)
+            {
+                if (l_serviceName == vpd::constants::pimServiceName)
+                {
+                    // The object is already under PIM. No need to process
+                    // again. Retain the old value.
+                    return;
+                }
+            }
+        }
+
+        // Implies value is not there in D-Bus. Populate it with default
+        // value "true".
+        vpd::types::PropertyMap l_functionalProp;
+        l_functionalProp.emplace("Functional", true);
+        vpd::vpdSpecificUtility::insertOrMerge(
+            io_interfaces, vpd::constants::operationalStatusInf,
+            move(l_functionalProp));
+    }
+
+    // if chassis is power on. Functional property should be there on D-Bus.
+    // Don't process.
+    return;
 }
 
 void PrimeInventory::processEnabledProperty(
-    [[maybe_unused]] const std::string& i_inventoryObjPath,
-    [[maybe_unused]] vpd::types::InterfaceMap& io_interfaces) const noexcept
+    const std::string& i_inventoryObjPath,
+    vpd::types::InterfaceMap& io_interfaces) const noexcept
 {
-    // ToDo: Populate interface to publish Enabled property on Dbus.
+    if (!vpd::dbusUtility::isChassisPowerOn())
+    {
+        std::vector<std::string> l_enableInf{vpd::constants::enableInf};
+
+        auto l_mapperObjectMap =
+            vpd::dbusUtility::getObjectMap(i_inventoryObjPath, l_enableInf);
+
+        // If the object has been found. Check if it is under PIM.
+        if (l_mapperObjectMap.size() != 0)
+        {
+            for (const auto& [l_serviceName, l_interfaceLsit] :
+                 l_mapperObjectMap)
+            {
+                if (l_serviceName == vpd::constants::pimServiceName)
+                {
+                    // The object is already under PIM. No need to process
+                    // again. Retain the old value.
+                    return;
+                }
+            }
+        }
+
+        // Implies value is not there in D-Bus. Populate it with default
+        // value "true".
+        vpd::types::PropertyMap l_enabledProp;
+        l_enabledProp.emplace("Enabled", true);
+        vpd::vpdSpecificUtility::insertOrMerge(
+            io_interfaces, vpd::constants::enableInf, move(l_enabledProp));
+    }
+
+    // if chassis is power on. Enabled property should be there on D-Bus.
+    // Don't process.
+    return;
 }
