diff --git a/vpd-manager/include/backup_restore.hpp b/vpd-manager/include/backup_restore.hpp
new file mode 100644
index 0000000..12ec384
--- /dev/null
+++ b/vpd-manager/include/backup_restore.hpp
@@ -0,0 +1,102 @@
+#pragma once
+
+#include "types.hpp"
+
+#include <nlohmann/json.hpp>
+
+#include <tuple>
+
+namespace vpd
+{
+
+// Backup and restore operation status.
+enum class BackupAndRestoreStatus : uint8_t
+{
+    NotStarted,
+    Invoked,
+    Completed
+};
+
+/**
+ * @brief class to implement backup and restore VPD.
+ *
+ */
+
+class BackupAndRestore
+{
+  public:
+    // delete functions
+    BackupAndRestore() = delete;
+    BackupAndRestore(const BackupAndRestore&) = delete;
+    BackupAndRestore& operator=(const BackupAndRestore&) = delete;
+    BackupAndRestore(BackupAndRestore&&) = delete;
+    BackupAndRestore& operator=(BackupAndRestore&&) = delete;
+
+    /**
+     * @brief Constructor.
+     *
+     * @param[in] i_sysCfgJsonObj - System config JSON object.
+     *
+     * @throw std::runtime_error in case constructor failure.
+     */
+    BackupAndRestore(const nlohmann::json& i_sysCfgJsonObj);
+
+    /**
+     * @brief Default destructor.
+     */
+    ~BackupAndRestore() = default;
+
+    /**
+     * @brief An API to backup and restore VPD.
+     *
+     * Note: This API works on the keywords declared in the backup and restore
+     * config JSON. Restore or backup action could be triggered for each
+     * keyword, based on the keyword's value present in the source and
+     * destination keyword.
+     *
+     * Restore source keyword's value with destination keyword's value,
+     * when source keyword has default value but
+     * destination's keyword has non default value.
+     *
+     * Backup the source keyword value to the destination's keyword's value,
+     * when source keyword has non default value but
+     * destination's keyword has default value.
+     *
+     * @return Tuple of updated source and destination VPD map variant.
+     */
+    std::tuple<types::VPDMapVariant, types::VPDMapVariant> backupAndRestore();
+
+    /**
+     * @brief An API to set backup and restore status.
+     *
+     * @param[in] i_status - Status to set.
+     */
+    static void
+        setBackupAndRestoreStatus(const BackupAndRestoreStatus& i_status);
+
+  private:
+    /**
+     * @brief An API to handle backup and restore of IPZ type VPD.
+     *
+     * @param[in,out] io_srcVpdMap - Source VPD map.
+     * @param[in,out] io_dstVpdMap - Destination VPD map.
+     * @param[in] i_srcPath - Source EEPROM file path or inventory path.
+     * @param[in] i_dstPath - Destination EEPROM file path or inventory path.
+     *
+     * @throw std::runtime_error
+     */
+    void backupAndRestoreIpzVpd(
+        types::IPZVpdMap& io_srcVpdMap, types::IPZVpdMap& io_dstVpdMap,
+        const std::string& i_srcPath, const std::string& i_dstPath);
+
+    // System JSON config JSON object.
+    nlohmann::json m_sysCfgJsonObj{};
+
+    // Backup and restore config JSON object.
+    nlohmann::json m_backupAndRestoreCfgJsonObj{};
+
+    // Backup and restore status.
+    static BackupAndRestoreStatus m_backupAndRestoreStatus;
+};
+
+} // namespace vpd
diff --git a/vpd-manager/include/bios_handler.hpp b/vpd-manager/include/bios_handler.hpp
new file mode 100644
index 0000000..916811e
--- /dev/null
+++ b/vpd-manager/include/bios_handler.hpp
@@ -0,0 +1,273 @@
+#pragma once
+#include "manager.hpp"
+#include "types.hpp"
+
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/bus.hpp>
+
+namespace vpd
+{
+
+/**
+ * @brief Interface class for BIOS handling.
+ *
+ * The class layout has the virtual methods required to be implemented by any
+ * concrete class that intends to use the feature provided via BIOS handler
+ * class.
+ */
+class BiosHandlerInterface
+{
+  public:
+    /**
+     * @brief API to back up or restore BIOS attributes.
+     *
+     * Concrete class should implement the API and read the backed up data from
+     * its designated location and take a call if it should be backed up or
+     * restored.
+     */
+    virtual void backUpOrRestoreBiosAttributes() = 0;
+
+    /**
+     * @brief Callback API to be triggered on BIOS attribute change.
+     *
+     * Concrete class should implement the API to extract the attribute and its
+     * value from DBus message broadcasted on BIOS attribute change.
+     * The definition should be overridden in concrete class to deal with BIOS
+     * attributes interested in.
+     *
+     * @param[in] i_msg - The callback message.
+     */
+    virtual void biosAttributesCallback(sdbusplus::message_t& i_msg) = 0;
+};
+
+/**
+ * @brief IBM specifc BIOS handler class.
+ */
+class IbmBiosHandler : public BiosHandlerInterface
+{
+  public:
+    /**
+     * @brief Construct a new IBM BIOS Handler object
+     *
+     * This constructor constructs a new IBM BIOS Handler object
+     * @param[in] i_manager - Manager object.
+     */
+    explicit IbmBiosHandler(const std::shared_ptr<Manager>& i_manager) :
+        m_manager(i_manager)
+    {}
+
+    /**
+     * @brief API to back up or restore BIOS attributes.
+     *
+     * The API will read the backed up data from the VPD keyword and based on
+     * its value, either backs up or restores the data.
+     */
+    virtual void backUpOrRestoreBiosAttributes();
+
+    /**
+     * @brief Callback API to be triggered on BIOS attribute change.
+     *
+     * The API to extract the required attribute and its value from DBus message
+     * broadcasted on BIOS attribute change.
+     *
+     * @param[in] i_msg - The callback message.
+     */
+    virtual void biosAttributesCallback(sdbusplus::message_t& i_msg);
+
+  private:
+    /**
+     * @brief API to read given attribute from BIOS table.
+     *
+     * @param[in] attributeName - Attribute to be read.
+     * @return - Bios attribute current value.
+     */
+    types::BiosAttributeCurrentValue
+        readBiosAttribute(const std::string& attributeName);
+
+    /**
+     * @brief API to process "hb_field_core_override" attribute.
+     *
+     * The API checks value stored in VPD. If found default then the BIOS value
+     * is saved to VPD else VPD value is restored in BIOS pending attribute
+     * table.
+     */
+    void processFieldCoreOverride();
+
+    /**
+     * @brief API to save FCO data into VPD.
+     *
+     * @param[in] i_fcoInBios - FCO value.
+     */
+    void saveFcoToVpd(int64_t i_fcoInBios);
+
+    /**
+     * @brief API to save given value to "hb_field_core_override" attribute.
+     *
+     * @param[in] i_fcoVal - FCO value.
+     */
+    void saveFcoToBios(const types::BinaryVector& i_fcoVal);
+
+    /**
+     * @brief API to save AMM data into VPD.
+     *
+     * @param[in] i_memoryMirrorMode - Memory mirror mode value.
+     */
+    void saveAmmToVpd(const std::string& i_memoryMirrorMode);
+
+    /**
+     * @brief API to save given value to "hb_memory_mirror_mode" attribute.
+     *
+     * @param[in] i_ammVal - AMM value.
+     */
+    void saveAmmToBios(const std::string& i_ammVal);
+
+    /**
+     * @brief API to process "hb_memory_mirror_mode" attribute.
+     *
+     * The API checks value stored in VPD. If found default then the BIOS value
+     * is saved to VPD else VPD value is restored in BIOS pending attribute
+     * table.
+     */
+    void processActiveMemoryMirror();
+
+    /**
+     * @brief API to process "pvm_create_default_lpar" attribute.
+     *
+     * The API reads the value from VPD and restore it to the BIOS attribute
+     * in BIOS pending attribute table.
+     */
+    void processCreateDefaultLpar();
+
+    /**
+     * @brief API to save given value to "pvm_create_default_lpar" attribute.
+     *
+     * @param[in] i_createDefaultLparVal - Value to be saved;
+     */
+    void saveCreateDefaultLparToBios(const std::string& i_createDefaultLparVal);
+
+    /**
+     * @brief API to save given value to VPD.
+     *
+     * @param[in] i_createDefaultLparVal - Value to be saved.
+     *
+     */
+    void saveCreateDefaultLparToVpd(const std::string& i_createDefaultLparVal);
+
+    /**
+     * @brief API to process "pvm_clear_nvram" attribute.
+     *
+     * The API reads the value from VPD and restores it to the BIOS pending
+     * attribute table.
+     */
+    void processClearNvram();
+
+    /**
+     * @brief API to save given value to "pvm_clear_nvram" attribute.
+     *
+     * @param[in] i_clearNvramVal - Value to be saved.
+     */
+    void saveClearNvramToBios(const std::string& i_clearNvramVal);
+
+    /**
+     * @brief API to save given value to VPD.
+     *
+     * @param[in] i_clearNvramVal - Value to be saved.
+     */
+    void saveClearNvramToVpd(const std::string& i_clearNvramVal);
+
+    /**
+     * @brief API to process "pvm_keep_and_clear" attribute.
+     *
+     * The API reads the value from VPD and restore it to the BIOS pending
+     * attribute table.
+     */
+    void processKeepAndClear();
+
+    /**
+     * @brief API to save given value to "pvm_keep_and_clear" attribute.
+     *
+     * @param[in] i_KeepAndClearVal - Value to be saved.
+     */
+    void saveKeepAndClearToBios(const std::string& i_KeepAndClearVal);
+
+    /**
+     * @brief API to save given value to VPD.
+     *
+     * @param[in] i_KeepAndClearVal - Value to be saved.
+     */
+    void saveKeepAndClearToVpd(const std::string& i_KeepAndClearVal);
+
+    // const reference to shared pointer to Manager object.
+    const std::shared_ptr<Manager>& m_manager;
+};
+
+/**
+ * @brief A class to operate upon BIOS attributes.
+ *
+ * The class along with specific BIOS handler class(es), provides a feature
+ * where specific BIOS attributes identified by the concrete specific class can
+ * be listened for any change and can be backed up to a desired location or
+ * restored back to the BIOS table.
+ *
+ * To use the feature, "BiosHandlerInterface" should be implemented by a
+ * concrete class and the same should be used to instantiate BiosHandler.
+ *
+ * This class registers call back to listen to PLDM service as it is being used
+ * for reading/writing BIOS attributes.
+ *
+ * The feature can be used in a factory reset scenario where backed up values
+ * can be used to restore BIOS.
+ *
+ */
+template <typename T>
+class BiosHandler
+{
+  public:
+    // deleted APIs
+    BiosHandler() = delete;
+    BiosHandler(const BiosHandler&) = delete;
+    BiosHandler& operator=(const BiosHandler&) = delete;
+    BiosHandler& operator=(BiosHandler&&) = delete;
+    ~BiosHandler() = default;
+
+    /**
+     * @brief Constructor.
+     *
+     * @param[in] i_connection - Asio connection object.
+     * @param[in] i_manager - Manager object.
+     */
+    BiosHandler(
+        const std::shared_ptr<sdbusplus::asio::connection>& i_connection,
+        const std::shared_ptr<Manager>& i_manager) : m_asioConn(i_connection)
+    {
+        m_specificBiosHandler = std::make_shared<T>(i_manager);
+        checkAndListenPldmService();
+    }
+
+  private:
+    /**
+     * @brief API to check if PLDM service is running and run BIOS sync.
+     *
+     * This API checks if the PLDM service is running and if yes it will start
+     * an immediate sync of BIOS attributes. If the service is not running, it
+     * registers a listener to be notified when the service starts so that a
+     * restore can be performed.
+     */
+    void checkAndListenPldmService();
+
+    /**
+     * @brief Register listener for BIOS attribute property change.
+     *
+     * The VPD manager needs to listen for property change of certain BIOS
+     * attributes that are backed in VPD. When the attributes change, the new
+     * value is written back to the VPD keywords that backs them up.
+     */
+    void listenBiosAttributes();
+
+    // Reference to the connection.
+    const std::shared_ptr<sdbusplus::asio::connection>& m_asioConn;
+
+    // shared pointer to specific BIOS handler.
+    std::shared_ptr<T> m_specificBiosHandler;
+};
+} // namespace vpd
diff --git a/vpd-manager/include/constants.hpp b/vpd-manager/include/constants.hpp
new file mode 100644
index 0000000..5faf8da
--- /dev/null
+++ b/vpd-manager/include/constants.hpp
@@ -0,0 +1,196 @@
+#pragma once
+
+#include <cstdint>
+#include <iostream>
+namespace vpd
+{
+namespace constants
+{
+static constexpr auto KEYWORD_SIZE = 2;
+static constexpr auto RECORD_SIZE = 4;
+
+static constexpr uint8_t IPZ_DATA_START = 11;
+static constexpr uint8_t IPZ_DATA_START_TAG = 0x84;
+static constexpr uint8_t IPZ_RECORD_END_TAG = 0x78;
+
+static constexpr uint8_t KW_VPD_DATA_START = 0;
+static constexpr uint8_t KW_VPD_START_TAG = 0x82;
+static constexpr uint8_t KW_VPD_PAIR_START_TAG = 0x84;
+static constexpr uint8_t ALT_KW_VPD_PAIR_START_TAG = 0x90;
+static constexpr uint8_t KW_VPD_END_TAG = 0x78;
+static constexpr uint8_t KW_VAL_PAIR_END_TAG = 0x79;
+static constexpr uint8_t AMM_ENABLED_IN_VPD = 2;
+static constexpr uint8_t AMM_DISABLED_IN_VPD = 1;
+
+static constexpr auto DDIMM_11S_BARCODE_START = 416;
+static constexpr auto DDIMM_11S_BARCODE_START_TAG = "11S";
+static constexpr auto DDIMM_11S_FORMAT_LEN = 3;
+static constexpr auto DDIMM_11S_BARCODE_LEN = 26;
+static constexpr auto PART_NUM_LEN = 7;
+static constexpr auto SERIAL_NUM_LEN = 12;
+static constexpr auto CCIN_LEN = 4;
+static constexpr auto CONVERT_MB_TO_KB = 1024;
+static constexpr auto CONVERT_GB_TO_KB = 1024 * 1024;
+
+static constexpr auto SPD_BYTE_2 = 2;
+static constexpr auto SPD_BYTE_3 = 3;
+static constexpr auto SPD_BYTE_4 = 4;
+static constexpr auto SPD_BYTE_6 = 6;
+static constexpr auto SPD_BYTE_12 = 12;
+static constexpr auto SPD_BYTE_13 = 13;
+static constexpr auto SPD_BYTE_18 = 18;
+static constexpr auto SPD_BYTE_234 = 234;
+static constexpr auto SPD_BYTE_235 = 235;
+static constexpr auto SPD_BYTE_BIT_0_3_MASK = 0x0F;
+static constexpr auto SPD_BYTE_MASK = 0xFF;
+static constexpr auto SPD_MODULE_TYPE_DDIMM = 0x0A;
+static constexpr auto SPD_DRAM_TYPE_DDR5 = 0x12;
+static constexpr auto SPD_DRAM_TYPE_DDR4 = 0x0C;
+
+static constexpr auto JEDEC_SDRAM_CAP_MASK = 0x0F;
+static constexpr auto JEDEC_PRI_BUS_WIDTH_MASK = 0x07;
+static constexpr auto JEDEC_SDRAM_WIDTH_MASK = 0x07;
+static constexpr auto JEDEC_NUM_RANKS_MASK = 0x38;
+static constexpr auto JEDEC_DIE_COUNT_MASK = 0x70;
+static constexpr auto JEDEC_SINGLE_LOAD_STACK = 0x02;
+static constexpr auto JEDEC_SIGNAL_LOADING_MASK = 0x03;
+
+static constexpr auto JEDEC_SDRAMCAP_MULTIPLIER = 256;
+static constexpr auto JEDEC_PRI_BUS_WIDTH_MULTIPLIER = 8;
+static constexpr auto JEDEC_SDRAM_WIDTH_MULTIPLIER = 4;
+static constexpr auto JEDEC_SDRAMCAP_RESERVED = 7;
+static constexpr auto JEDEC_RESERVED_BITS = 3;
+static constexpr auto JEDEC_DIE_COUNT_RIGHT_SHIFT = 4;
+
+static constexpr auto LAST_KW = "PF";
+static constexpr auto POUND_KW = '#';
+static constexpr auto POUND_KW_PREFIX = "PD_";
+static constexpr auto MB_YEAR_END = 4;
+static constexpr auto MB_MONTH_END = 7;
+static constexpr auto MB_DAY_END = 10;
+static constexpr auto MB_HOUR_END = 13;
+static constexpr auto MB_MIN_END = 16;
+static constexpr auto MB_RESULT_LEN = 19;
+static constexpr auto MB_LEN_BYTES = 8;
+static constexpr auto UUID_LEN_BYTES = 16;
+static constexpr auto UUID_TIME_LOW_END = 8;
+static constexpr auto UUID_TIME_MID_END = 13;
+static constexpr auto UUID_TIME_HIGH_END = 18;
+static constexpr auto UUID_CLK_SEQ_END = 23;
+static constexpr auto MAC_ADDRESS_LEN_BYTES = 6;
+static constexpr auto ONE_BYTE = 1;
+static constexpr auto TWO_BYTES = 2;
+
+static constexpr auto VALUE_0 = 0;
+static constexpr auto VALUE_1 = 1;
+static constexpr auto VALUE_2 = 2;
+static constexpr auto VALUE_3 = 3;
+static constexpr auto VALUE_4 = 4;
+static constexpr auto VALUE_5 = 5;
+static constexpr auto VALUE_6 = 6;
+static constexpr auto VALUE_7 = 7;
+static constexpr auto VALUE_8 = 8;
+
+static constexpr auto MASK_BYTE_BITS_01 = 0x03;
+static constexpr auto MASK_BYTE_BITS_345 = 0x38;
+static constexpr auto MASK_BYTE_BITS_012 = 0x07;
+static constexpr auto MASK_BYTE_BITS_567 = 0xE0;
+static constexpr auto MASK_BYTE_BITS_01234 = 0x1F;
+
+static constexpr auto MASK_BYTE_BIT_6 = 0x40;
+static constexpr auto MASK_BYTE_BIT_7 = 0x80;
+
+static constexpr auto SHIFT_BITS_0 = 0;
+static constexpr auto SHIFT_BITS_3 = 3;
+static constexpr auto SHIFT_BITS_5 = 5;
+
+static constexpr auto ASCII_OF_SPACE = 32;
+
+// Size of 8 EQs' in CP00's PG keyword
+static constexpr auto SIZE_OF_8EQ_IN_PG = 24;
+
+// Zero based index position of first EQ in CP00's PG keyword
+static constexpr auto INDEX_OF_EQ0_IN_PG = 97;
+
+constexpr auto systemInvPath = "/xyz/openbmc_project/inventory/system";
+constexpr auto pimPath = "/xyz/openbmc_project/inventory";
+constexpr auto pimIntf = "xyz.openbmc_project.Inventory.Manager";
+constexpr auto ipzVpdInf = "com.ibm.ipzvpd.";
+constexpr auto kwdVpdInf = "com.ibm.ipzvpd.VINI";
+constexpr auto vsysInf = "com.ibm.ipzvpd.VSYS";
+constexpr auto utilInf = "com.ibm.ipzvpd.UTIL";
+constexpr auto vcenInf = "com.ibm.ipzvpd.VCEN";
+constexpr auto kwdCCIN = "CC";
+constexpr auto kwdRG = "RG";
+constexpr auto kwdAMM = "D0";
+constexpr auto kwdClearNVRAM_CreateLPAR = "D1";
+constexpr auto kwdKeepAndClear = "D1";
+constexpr auto kwdFC = "FC";
+constexpr auto kwdTM = "TM";
+constexpr auto kwdSE = "SE";
+constexpr auto recVSYS = "VSYS";
+constexpr auto recVCEN = "VCEN";
+constexpr auto locationCodeInf = "com.ibm.ipzvpd.Location";
+constexpr auto xyzLocationCodeInf =
+    "xyz.openbmc_project.Inventory.Decorator.LocationCode";
+constexpr auto operationalStatusInf =
+    "xyz.openbmc_project.State.Decorator.OperationalStatus";
+constexpr auto enableInf = "xyz.openbmc_project.Object.Enable";
+constexpr auto assetInf = "xyz.openbmc_project.Inventory.Decorator.Asset";
+constexpr auto inventoryItemInf = "xyz.openbmc_project.Inventory.Item";
+constexpr auto pldmServiceName = "xyz.openbmc_project.PLDM";
+constexpr auto pimServiceName = "xyz.openbmc_project.Inventory.Manager";
+constexpr auto biosConfigMgrObjPath =
+    "/xyz/openbmc_project/bios_config/manager";
+constexpr auto biosConfigMgrService = "xyz.openbmc_project.BIOSConfigManager";
+constexpr auto biosConfigMgrInterface =
+    "xyz.openbmc_project.BIOSConfig.Manager";
+constexpr auto objectMapperService = "xyz.openbmc_project.ObjectMapper";
+constexpr auto objectMapperPath = "/xyz/openbmc_project/object_mapper";
+constexpr auto objectMapperInf = "xyz.openbmc_project.ObjectMapper";
+constexpr auto systemVpdInvPath =
+    "/xyz/openbmc_project/inventory/system/chassis/motherboard";
+constexpr auto assetTagInf = "xyz.openbmc_project.Inventory.Decorator.AssetTag";
+constexpr auto hostObjectPath = "/xyz/openbmc_project/state/host0";
+constexpr auto hostInterface = "xyz.openbmc_project.State.Host";
+constexpr auto hostService = "xyz.openbmc_project.State.Host";
+constexpr auto hostRunningState =
+    "xyz.openbmc_project.State.Host.HostState.Running";
+static constexpr auto BD_YEAR_END = 4;
+static constexpr auto BD_MONTH_END = 7;
+static constexpr auto BD_DAY_END = 10;
+static constexpr auto BD_HOUR_END = 13;
+
+constexpr uint8_t UNEXP_LOCATION_CODE_MIN_LENGTH = 4;
+constexpr uint8_t EXP_LOCATION_CODE_MIN_LENGTH = 17;
+static constexpr auto SE_KWD_LENGTH = 7;
+static constexpr auto INVALID_NODE_NUMBER = -1;
+
+static constexpr auto CMD_BUFFER_LENGTH = 256;
+
+// To be explicitly used for string comparision.
+static constexpr auto STR_CMP_SUCCESS = 0;
+
+// Just a random value. Can be adjusted as required.
+static constexpr uint8_t MAX_THREADS = 10;
+
+static constexpr auto FAILURE = -1;
+static constexpr auto SUCCESS = 0;
+
+constexpr auto bmcStateService = "xyz.openbmc_project.State.BMC";
+constexpr auto bmcZeroStateObject = "/xyz/openbmc_project/state/bmc0";
+constexpr auto bmcStateInterface = "xyz.openbmc_project.State.BMC";
+constexpr auto currentBMCStateProperty = "CurrentBMCState";
+constexpr auto bmcReadyState = "xyz.openbmc_project.State.BMC.BMCState.Ready";
+
+static constexpr auto eventLoggingServiceName = "xyz.openbmc_project.Logging";
+static constexpr auto eventLoggingObjectPath = "/xyz/openbmc_project/logging";
+static constexpr auto eventLoggingInterface =
+    "xyz.openbmc_project.Logging.Create";
+
+static constexpr auto systemdService = "org.freedesktop.systemd1";
+static constexpr auto systemdObjectPath = "/org/freedesktop/systemd1";
+static constexpr auto systemdManagerInterface =
+    "org.freedesktop.systemd1.Manager";
+} // namespace constants
+} // namespace vpd
diff --git a/vpd-manager/include/ddimm_parser.hpp b/vpd-manager/include/ddimm_parser.hpp
new file mode 100644
index 0000000..a53ed17
--- /dev/null
+++ b/vpd-manager/include/ddimm_parser.hpp
@@ -0,0 +1,123 @@
+#pragma once
+
+#include "constants.hpp"
+#include "exceptions.hpp"
+#include "logger.hpp"
+#include "parser_interface.hpp"
+#include "types.hpp"
+
+namespace vpd
+{
+/**
+ * @brief Concrete class to implement DDIMM VPD parsing.
+ *
+ * The class inherits ParserInterface interface class and overrides the parser
+ * functionality to implement parsing logic for DDIMM VPD format.
+ */
+class DdimmVpdParser : public ParserInterface
+{
+  public:
+    // Deleted API's
+    DdimmVpdParser() = delete;
+    DdimmVpdParser(const DdimmVpdParser&) = delete;
+    DdimmVpdParser& operator=(const DdimmVpdParser&) = delete;
+    DdimmVpdParser(DdimmVpdParser&&) = delete;
+    DdimmVpdParser& operator=(DdimmVpdParser&&) = delete;
+
+    /**
+     * @brief Defaul destructor.
+     */
+    ~DdimmVpdParser() = default;
+
+    /**
+     * @brief Constructor
+     *
+     * @param[in] i_vpdVector - VPD data.
+     */
+    DdimmVpdParser(const types::BinaryVector& i_vpdVector) :
+        m_vpdVector(i_vpdVector)
+    {
+        if ((constants::DDIMM_11S_BARCODE_START +
+             constants::DDIMM_11S_BARCODE_LEN) > m_vpdVector.size())
+        {
+            throw(DataException("Malformed DDIMM VPD"));
+        }
+    }
+
+    /**
+     * @brief API to parse DDIMM VPD file.
+     *
+     * @return parsed VPD data
+     */
+    virtual types::VPDMapVariant parse() override;
+
+  private:
+    /**
+     * @brief API to read keyword data based on the type DDR4/DDR5.
+     *
+     * Updates the m_parsedVpdMap with read keyword data.
+     * @param[in] i_iterator - iterator to buffer containing VPD
+     */
+    void readKeywords(types::BinaryVector::const_iterator i_iterator);
+
+    /**
+     * @brief API to calculate DDIMM size from DDIMM VPD
+     *
+     * @param[in] i_iterator - iterator to buffer containing VPD
+     * @return calculated size or 0 in case of any error.
+     */
+    size_t getDdimmSize(types::BinaryVector::const_iterator i_iterator);
+
+    /**
+     * @brief This function calculates DDR5 based DDIMM's capacity
+     *
+     * @param[in] i_iterator - iterator to buffer containing VPD
+     * @return calculated size or 0 in case of any error.
+     */
+    size_t
+        getDdr5BasedDdimmSize(types::BinaryVector::const_iterator i_iterator);
+
+    /**
+     * @brief This function calculates DDR4 based DDIMM's capacity
+     *
+     * @param[in] i_iterator - iterator to buffer containing VPD
+     * @return calculated size or 0 in case of any error.
+     */
+    size_t
+        getDdr4BasedDdimmSize(types::BinaryVector::const_iterator i_iterator);
+
+    /**
+     * @brief This function calculates DDR5 based die per package
+     *
+     * @param[in] i_ByteValue - the bit value for calculation
+     * @return die per package value.
+     */
+    uint8_t getDdr5DiePerPackage(uint8_t i_ByteValue);
+
+    /**
+     * @brief This function calculates DDR5 based density per die
+     *
+     * @param[in] i_ByteValue - the bit value for calculation
+     * @return density per die.
+     */
+    uint8_t getDdr5DensityPerDie(uint8_t i_ByteValue);
+
+    /**
+     * @brief This function checks the validity of the bits
+     *
+     * @param[in] i_ByteValue - the byte value with relevant bits
+     * @param[in] i_shift - shifter value to selects needed bits
+     * @param[in] i_minValue - minimum value it can contain
+     * @param[in] i_maxValue - maximum value it can contain
+     * @return true if valid else false.
+     */
+    bool checkValidValue(uint8_t i_ByteValue, uint8_t i_shift,
+                         uint8_t i_minValue, uint8_t i_maxValue);
+
+    // VPD file to be parsed
+    const types::BinaryVector& m_vpdVector;
+
+    // Stores parsed VPD data.
+    types::DdimmVpdMap m_parsedVpdMap{};
+};
+} // namespace vpd
diff --git a/vpd-manager/include/event_logger.hpp b/vpd-manager/include/event_logger.hpp
new file mode 100644
index 0000000..0080be6
--- /dev/null
+++ b/vpd-manager/include/event_logger.hpp
@@ -0,0 +1,170 @@
+#pragma once
+
+#include "constants.hpp"
+#include "types.hpp"
+
+#include <iostream>
+#include <optional>
+#include <string>
+#include <unordered_map>
+
+namespace vpd
+{
+/**
+ * @brief Class for logging events.
+ *
+ * Class handles logging PEL under 'logging' service.
+ * Provide separate async API's for calling out inventory_path, device_path and
+ * i2c bus.
+ */
+class EventLogger
+{
+  public:
+    /**
+     * @brief An API to create a PEL with inventory path callout.
+     *
+     * This API calls an async method to create PEL, and also handles inventory
+     * path callout.
+     *
+     * Note: If inventory path callout info is not provided, it will create a
+     * PEL without any callout. Currently only one callout is handled in this
+     * API.
+     *
+     * @todo: Symbolic FRU and procedure callout needs to be handled in this
+     * API.
+     *
+     * @param[in] i_errorType - Enum to map with event message name.
+     * @param[in] i_severity - Severity of the event.
+     * @param[in] i_callouts - Callout information, list of tuple having
+     * inventory path and priority as input [optional].
+     * @param[in] i_fileName - File name.
+     * @param[in] i_funcName - Function name.
+     * @param[in] i_internalRc - Internal return code.
+     * @param[in] i_description - Error description.
+     * @param[in] i_userData1 - Additional user data [optional].
+     * @param[in] i_userData2 - Additional user data [optional].
+     * @param[in] i_symFru - Symblolic FRU callout data [optional].
+     * @param[in] i_procedure - Procedure callout data [optional].
+     *
+     * @throw exception in case of error.
+     */
+    static void createAsyncPelWithInventoryCallout(
+        const types::ErrorType& i_errorType,
+        const types::SeverityType& i_severity,
+        const std::vector<types::InventoryCalloutData>& i_callouts,
+        const std::string& i_fileName, const std::string& i_funcName,
+        const uint8_t i_internalRc, const std::string& i_description,
+        const std::optional<std::string> i_userData1,
+        const std::optional<std::string> i_userData2,
+        const std::optional<std::string> i_symFru,
+        const std::optional<std::string> i_procedure);
+
+    /**
+     * @brief An API to create a PEL with device path callout.
+     *
+     * @param[in] i_errorType - Enum to map with event message name.
+     * @param[in] i_severity - Severity of the event.
+     * @param[in] i_callouts - Callout information, list of tuple having device
+     * path and error number as input.
+     * @param[in] i_fileName - File name.
+     * @param[in] i_funcName - Function name.
+     * @param[in] i_internalRc - Internal return code.
+     * @param[in] i_userData1 - Additional user data [optional].
+     * @param[in] i_userData2 - Additional user data [optional].
+     */
+    static void createAsyncPelWithI2cDeviceCallout(
+        const types::ErrorType i_errorType,
+        const types::SeverityType i_severity,
+        const std::vector<types::DeviceCalloutData>& i_callouts,
+        const std::string& i_fileName, const std::string& i_funcName,
+        const uint8_t i_internalRc,
+        const std::optional<std::pair<std::string, std::string>> i_userData1,
+        const std::optional<std::pair<std::string, std::string>> i_userData2);
+
+    /**
+     * @brief An API to create a PEL with I2c bus callout.
+     *
+     * @param[in] i_errorType - Enum to map with event message name.
+     * @param[in] i_severity - Severity of the event.
+     * @param[in] i_callouts - Callout information, list of tuple having i2c
+     * bus, i2c address and error number as input.
+     * @param[in] i_fileName - File name.
+     * @param[in] i_funcName - Function name.
+     * @param[in] i_internalRc - Internal return code.
+     * @param[in] i_userData1 - Additional user data [optional].
+     * @param[in] i_userData2 - Additional user data [optional].
+     */
+    static void createAsyncPelWithI2cBusCallout(
+        const types::ErrorType i_errorType,
+        const types::SeverityType i_severity,
+        const std::vector<types::I2cBusCalloutData>& i_callouts,
+        const std::string& i_fileName, const std::string& i_funcName,
+        const uint8_t i_internalRc,
+        const std::optional<std::pair<std::string, std::string>> i_userData1,
+        const std::optional<std::pair<std::string, std::string>> i_userData2);
+
+    /**
+     * @brief An API to create a PEL.
+     *
+     * @param[in] i_errorType - Enum to map with event message name.
+     * @param[in] i_severity - Severity of the event.
+     * @param[in] i_fileName - File name.
+     * @param[in] i_funcName - Function name.
+     * @param[in] i_internalRc - Internal return code.
+     * @param[in] i_description - Error description.
+     * @param[in] i_userData1 - Additional user data [optional].
+     * @param[in] i_userData2 - Additional user data [optional].
+     * @param[in] i_symFru - Symblolic FRU callout data [optional].
+     * @param[in] i_procedure - Procedure callout data [optional].
+     *
+     * @todo: Symbolic FRU and procedure callout needs to be handled in this
+     * API.
+     */
+    static void createAsyncPel(
+        const types::ErrorType& i_errorType,
+        const types::SeverityType& i_severity, const std::string& i_fileName,
+        const std::string& i_funcName, const uint8_t i_internalRc,
+        const std::string& i_description,
+        const std::optional<std::string> i_userData1,
+        const std::optional<std::string> i_userData2,
+        const std::optional<std::string> i_symFru,
+        const std::optional<std::string> i_procedure);
+
+    /**
+     * @brief An API to create PEL.
+     *
+     * This API makes synchronous call to phosphor-logging Create method.
+     *
+     * @param[in] i_errorType - Enum to map with event message name.
+     * @param[in] i_severity - Severity of the event.
+     * @param[in] i_fileName - File name.
+     * @param[in] i_funcName - Function name.
+     * @param[in] i_internalRc - Internal return code.
+     * @param[in] i_description - Error description.
+     * @param[in] i_userData1 - Additional user data [optional].
+     * @param[in] i_userData2 - Additional user data [optional].
+     * @param[in] i_symFru - Symblolic FRU callout data [optional].s
+     * @param[in] i_procedure - Procedure callout data [optional].
+     *
+     * @todo: Symbolic FRU and procedure callout needs to be handled in this
+     * API.
+     */
+    static void createSyncPel(
+        const types::ErrorType& i_errorType,
+        const types::SeverityType& i_severity, const std::string& i_fileName,
+        const std::string& i_funcName, const uint8_t i_internalRc,
+        const std::string& i_description,
+        const std::optional<std::string> i_userData1,
+        const std::optional<std::string> i_userData2,
+        const std::optional<std::string> i_symFru,
+        const std::optional<std::string> i_procedure);
+
+  private:
+    static const std::unordered_map<types::SeverityType, std::string>
+        m_severityMap;
+    static const std::unordered_map<types::ErrorType, std::string>
+        m_errorMsgMap;
+    static const std::unordered_map<types::CalloutPriority, std::string>
+        m_priorityMap;
+};
+} // namespace vpd
diff --git a/vpd-manager/include/exceptions.hpp b/vpd-manager/include/exceptions.hpp
new file mode 100644
index 0000000..a787d08
--- /dev/null
+++ b/vpd-manager/include/exceptions.hpp
@@ -0,0 +1,157 @@
+#pragma once
+
+#include <stdexcept>
+
+namespace vpd
+{
+/** @class Exception
+ * @brief This class inherits std::runtime_error and overrrides "what" method
+ * to return the description of exception.
+ * This class also works as base class for custom exception classes for
+ * VPD repository.
+ */
+class Exception : public std::runtime_error
+{
+  public:
+    // deleted methods
+    Exception() = delete;
+    Exception(const Exception&) = delete;
+    Exception(Exception&&) = delete;
+    Exception& operator=(const Exception&) = delete;
+
+    // default destructor
+    ~Exception() = default;
+
+    /** @brief constructor
+     *
+     *  @param[in] msg - Information w.r.t exception.
+     */
+    explicit Exception(const std::string& msg) :
+        std::runtime_error(msg), m_errMsg(msg)
+    {}
+
+    /** @brief inline method to return exception string.
+     *
+     * This is overridden method of std::runtime class.
+     */
+    inline const char* what() const noexcept override
+    {
+        return m_errMsg.c_str();
+    }
+
+  private:
+    /** @brief string to hold the reason of exception */
+    std::string m_errMsg;
+
+}; // class Exception
+
+/** @class EccException
+ *
+ *  @brief This class extends Exceptions class and define type for ECC related
+ * exception in VPD.
+ */
+class EccException : public Exception
+{
+  public:
+    // deleted methods
+    EccException() = delete;
+    EccException(const EccException&) = delete;
+    EccException(EccException&&) = delete;
+    EccException& operator=(const EccException&) = delete;
+
+    // default destructor
+    ~EccException() = default;
+
+    /** @brief constructor
+     *
+     *  @param[in] msg - Information w.r.t exception.
+     */
+    explicit EccException(const std::string& msg) : Exception(msg) {}
+
+}; // class EccException
+
+/** @class DataException
+ *
+ * @brief This class extends Exceptions class and define type for data related
+ * exception in VPD
+ */
+class DataException : public Exception
+{
+  public:
+    // deleted methods
+    DataException() = delete;
+    DataException(const DataException&) = delete;
+    DataException(DataException&&) = delete;
+    DataException& operator=(const DataException&) = delete;
+
+    // default destructor
+    ~DataException() = default;
+
+    /** @brief constructor
+     *
+     *  @param[in] msg - string to define exception
+     */
+    explicit DataException(const std::string& msg) : Exception(msg) {}
+
+}; // class DataException
+
+class JsonException : public Exception
+{
+  public:
+    // deleted methods
+    JsonException() = delete;
+    JsonException(const JsonException&) = delete;
+    JsonException(JsonException&&) = delete;
+    JsonException& operator=(const JsonException&) = delete;
+
+    // default destructor
+    ~JsonException() = default;
+
+    /** @brief constructor
+     *  @param[in] msg - Information w.r.t. exception.
+     *  @param[in] path - Json path
+     */
+    JsonException(const std::string& msg, const std::string& path) :
+        Exception(msg), m_jsonPath(path)
+    {}
+
+    /** @brief Json path getter method.
+     *
+     *  @return - Json path
+     */
+    inline std::string getJsonPath() const
+    {
+        return m_jsonPath;
+    }
+
+  private:
+    /** To hold the path of Json that failed*/
+    std::string m_jsonPath;
+
+}; // class JSonException
+
+/** @class GpioException
+ *  @brief Custom handler for GPIO exception.
+ *
+ *  This class extends Exceptions class and define
+ *  type for GPIO related exception in VPD.
+ */
+class GpioException : public Exception
+{
+  public:
+    // deleted methods
+    GpioException() = delete;
+    GpioException(const GpioException&) = delete;
+    GpioException(GpioException&&) = delete;
+    GpioException& operator=(const GpioException&) = delete;
+
+    // default destructor
+    ~GpioException() = default;
+
+    /** @brief constructor
+     *  @param[in] msg - string to define exception
+     */
+    explicit GpioException(const std::string& msg) : Exception(msg) {}
+};
+
+} // namespace vpd
diff --git a/vpd-manager/include/gpio_monitor.hpp b/vpd-manager/include/gpio_monitor.hpp
new file mode 100644
index 0000000..476a31d
--- /dev/null
+++ b/vpd-manager/include/gpio_monitor.hpp
@@ -0,0 +1,142 @@
+#pragma once
+
+#include "worker.hpp"
+
+#include <boost/asio/steady_timer.hpp>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/asio/connection.hpp>
+
+#include <vector>
+
+namespace vpd
+{
+/**
+ * @brief class for GPIO event handling.
+ *
+ * Responsible for detecting events and handling them. It continuously
+ * monitors the presence of the FRU. If it detects any change, performs
+ * deletion of FRU VPD if FRU is not present, otherwise performs VPD
+ * collection if FRU gets added.
+ */
+class GpioEventHandler
+{
+  public:
+    GpioEventHandler() = delete;
+    ~GpioEventHandler() = default;
+    GpioEventHandler(const GpioEventHandler&) = delete;
+    GpioEventHandler& operator=(const GpioEventHandler&) = delete;
+    GpioEventHandler(GpioEventHandler&&) = delete;
+    GpioEventHandler& operator=(GpioEventHandler&&) = delete;
+
+    /**
+     * @brief Constructor
+     *
+     * @param[in] i_fruPath - EEPROM path of the FRU.
+     * @param[in] i_worker - pointer to the worker object.
+     * @param[in] i_ioContext - pointer to the io context object
+     */
+    GpioEventHandler(
+        const std::string i_fruPath, const std::shared_ptr<Worker>& i_worker,
+        const std::shared_ptr<boost::asio::io_context>& i_ioContext) :
+        m_fruPath(i_fruPath), m_worker(i_worker)
+    {
+        setEventHandlerForGpioPresence(i_ioContext);
+    }
+
+  private:
+    /**
+     * @brief API to take action based on GPIO presence pin value.
+     *
+     * This API takes action based on the change in the presence pin value.
+     * It performs deletion of FRU VPD if FRU is not present, otherwise performs
+     * VPD collection if FRU gets added.
+     *
+     * @param[in] i_isFruPresent - Holds the present status of the FRU.
+     */
+    void handleChangeInGpioPin(const bool& i_isFruPresent);
+
+    /**
+     * @brief An API to set event handler for FRUs GPIO presence.
+     *
+     * An API to set timer to call event handler to detect GPIO presence
+     * of the FRU.
+     *
+     * @param[in] i_ioContext - pointer to io context object
+     */
+    void setEventHandlerForGpioPresence(
+        const std::shared_ptr<boost::asio::io_context>& i_ioContext);
+
+    /**
+     * @brief API to handle timer expiry.
+     *
+     * This API handles timer expiry and checks on the GPIO presence state,
+     * takes action if there is any change in the GPIO presence value.
+     *
+     * @param[in] i_errorCode - Error Code
+     * @param[in] i_timerObj - Pointer to timer Object.
+     */
+    void handleTimerExpiry(
+        const boost::system::error_code& i_errorCode,
+        const std::shared_ptr<boost::asio::steady_timer>& i_timerObj);
+
+    const std::string m_fruPath;
+
+    const std::shared_ptr<Worker>& m_worker;
+
+    // Preserves the GPIO pin value to compare. Default value is false.
+    bool m_prevPresencePinValue = false;
+};
+
+class GpioMonitor
+{
+  public:
+    GpioMonitor() = delete;
+    ~GpioMonitor() = default;
+    GpioMonitor(const GpioMonitor&) = delete;
+    GpioMonitor& operator=(const GpioMonitor&) = delete;
+    GpioMonitor(GpioMonitor&&) = delete;
+    GpioMonitor& operator=(GpioMonitor&&) = delete;
+
+    /**
+     * @brief constructor
+     *
+     * @param[in] i_sysCfgJsonObj - System config JSON Object.
+     * @param[in] i_worker - pointer to the worker object.
+     * @param[in] i_ioContext - pointer to IO context object.
+     */
+    GpioMonitor(const nlohmann::json i_sysCfgJsonObj,
+                const std::shared_ptr<Worker>& i_worker,
+                const std::shared_ptr<boost::asio::io_context>& i_ioContext) :
+        m_sysCfgJsonObj(i_sysCfgJsonObj)
+    {
+        if (!m_sysCfgJsonObj.empty())
+        {
+            initHandlerForGpio(i_ioContext, i_worker);
+        }
+        else
+        {
+            throw std::runtime_error(
+                "Gpio Monitoring can't be instantiated with empty config JSON");
+        }
+    }
+
+  private:
+    /**
+     * @brief API to instantiate GpioEventHandler for GPIO pins.
+     *
+     * This API will extract the GPIO information from system config JSON
+     * and instantiate event handler for GPIO pins.
+     *
+     * @param[in] i_ioContext - Pointer to IO context object.
+     * @param[in] i_worker - Pointer to worker class.
+     */
+    void initHandlerForGpio(
+        const std::shared_ptr<boost::asio::io_context>& i_ioContext,
+        const std::shared_ptr<Worker>& i_worker);
+
+    // Array of event handlers for all the attachable FRUs.
+    std::vector<std::shared_ptr<GpioEventHandler>> m_gpioEventHandlerObjects;
+
+    const nlohmann::json& m_sysCfgJsonObj;
+};
+} // namespace vpd
diff --git a/vpd-manager/include/ipz_parser.hpp b/vpd-manager/include/ipz_parser.hpp
new file mode 100644
index 0000000..2d50ddd
--- /dev/null
+++ b/vpd-manager/include/ipz_parser.hpp
@@ -0,0 +1,273 @@
+#pragma once
+
+#include "logger.hpp"
+#include "parser_interface.hpp"
+#include "types.hpp"
+
+#include <fstream>
+#include <string_view>
+
+namespace vpd
+{
+/**
+ * @brief Concrete class to implement IPZ VPD parsing.
+ *
+ * The class inherits ParserInterface interface class and overrides the parser
+ * functionality to implement parsing logic for IPZ VPD format.
+ */
+class IpzVpdParser : public ParserInterface
+{
+  public:
+    // Deleted APIs
+    IpzVpdParser() = delete;
+    IpzVpdParser(const IpzVpdParser&) = delete;
+    IpzVpdParser& operator=(const IpzVpdParser&) = delete;
+    IpzVpdParser(IpzVpdParser&&) = delete;
+    IpzVpdParser& operator=(IpzVpdParser&&) = delete;
+
+    /**
+     * @brief Constructor.
+     *
+     * @param[in] vpdVector - VPD data.
+     * @param[in] vpdFilePath - Path to VPD EEPROM.
+     * @param[in] vpdStartOffset - Offset from where VPD starts in the file.
+     * Defaulted to 0.
+     */
+    IpzVpdParser(const types::BinaryVector& vpdVector,
+                 const std::string& vpdFilePath, size_t vpdStartOffset = 0) :
+        m_vpdVector(vpdVector), m_vpdFilePath(vpdFilePath),
+        m_vpdStartOffset(vpdStartOffset)
+    {
+        try
+        {
+            m_vpdFileStream.exceptions(
+                std::ifstream::badbit | std::ifstream::failbit);
+            m_vpdFileStream.open(vpdFilePath, std::ios::in | std::ios::out |
+                                                  std::ios::binary);
+        }
+        catch (const std::fstream::failure& e)
+        {
+            logging::logMessage(e.what());
+        }
+    }
+
+    /**
+     * @brief Defaul destructor.
+     */
+    ~IpzVpdParser() = default;
+
+    /**
+     * @brief API to parse IPZ VPD file.
+     *
+     * Note: Caller needs to check validity of the map returned. Throws
+     * exception in certain situation, needs to be handled accordingly.
+     *
+     * @return parsed VPD data.
+     */
+    virtual types::VPDMapVariant parse() override;
+
+    /**
+     * @brief API to check validity of VPD header.
+     *
+     * Note: The API throws exception in case of any failure or malformed VDP.
+     *
+     * @param[in] itrToVPD - Iterator to the beginning of VPD file.
+     * Don't change the parameter to reference as movement of passsed iterator
+     * to an offset is not required after header check.
+     */
+    void checkHeader(types::BinaryVector::const_iterator itrToVPD);
+
+    /**
+     * @brief API to read keyword's value from hardware
+     *
+     * @param[in] i_paramsToReadData - Data required to perform read
+     *
+     * @throw
+     * sdbusplus::xyz::openbmc_project::Common::Device::Error::ReadFailure.
+     *
+     * @return On success return the value read. On failure throw exception.
+     */
+    types::DbusVariantType
+        readKeywordFromHardware(const types::ReadVpdParams i_paramsToReadData);
+
+    /**
+     * @brief API to write keyword's value on hardware.
+     *
+     * @param[in] i_paramsToWriteData - Data required to perform write.
+     *
+     * @throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument.
+     * @throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed.
+     * @throw DataException
+     * @throw EccException
+     *
+     *
+     * @return On success returns number of bytes written on hardware, On
+     * failure throws exception.
+     */
+    int writeKeywordOnHardware(const types::WriteVpdParams i_paramsToWriteData);
+
+  private:
+    /**
+     * @brief Check ECC of VPD header.
+     *
+     * @return true/false based on check result.
+     */
+    bool vhdrEccCheck();
+
+    /**
+     * @brief Check ECC of VTOC.
+     *
+     * @return true/false based on check result.
+     */
+    bool vtocEccCheck();
+
+    /**
+     * @brief Check ECC of a record.
+     *
+     * Note: Throws exception in case of failure. Caller need to handle as
+     * required.
+     *
+     * @param[in] iterator - Iterator to the record.
+     * @return success/failre
+     */
+    bool recordEccCheck(types::BinaryVector::const_iterator iterator);
+
+    /**
+     * @brief API to read VTOC record.
+     *
+     * The API reads VTOC record and returns the length of PT keyword.
+     *
+     * Note: Throws exception in case of any error. Caller need to handle as
+     * required.
+     *
+     * @param[in] itrToVPD - Iterator to begining of VPD data.
+     * @return Length of PT keyword.
+     */
+    auto readTOC(types::BinaryVector::const_iterator& itrToVPD);
+
+    /**
+     * @brief API to read PT record.
+     *
+     * Note: Throws exception in case ECC check fails.
+     *
+     * @param[in] itrToPT - Iterator to PT record in VPD vector.
+     * @param[in] ptLength - length of the PT record.
+     * @return List of record's offset.
+     */
+    types::RecordOffsetList readPT(types::BinaryVector::const_iterator& itrToPT,
+                                   auto ptLength);
+
+    /**
+     * @brief API to read keyword data based on its encoding type.
+     *
+     * @param[in] kwdName - Name of the keyword.
+     * @param[in] kwdDataLength - Length of keyword data.
+     * @param[in] itrToKwdData - Iterator to start of keyword data.
+     * @return keyword data, empty otherwise.
+     */
+    std::string readKwData(std::string_view kwdName, std::size_t kwdDataLength,
+                           types::BinaryVector::const_iterator itrToKwdData);
+
+    /**
+     * @brief API to read keyword and its value under a record.
+     *
+     * @param[in] iterator - pointer to the start of keywords under the record.
+     * @return keyword-value map of keywords under that record.
+     */
+    types::IPZVpdMap::mapped_type
+        readKeywords(types::BinaryVector::const_iterator& itrToKwds);
+
+    /**
+     * @brief API to process a record.
+     *
+     * @param[in] recordOffset - Offset of the record in VPD.
+     */
+    void processRecord(auto recordOffset);
+
+    /**
+     * @brief Get keyword's value from record
+     *
+     * @param[in] i_record - Record's name
+     * @param[in] i_keyword - Keyword's name
+     * @param[in] i_recordDataOffset - Record's offset value
+     *
+     * @throw std::runtime_error
+     *
+     * @return On success return bytes read, on failure throws error.
+     */
+    types::BinaryVector getKeywordValueFromRecord(
+        const types::Record& i_recordName, const types::Keyword& i_keywordName,
+        const types::RecordOffset& i_recordDataOffset);
+
+    /**
+     * @brief Get record's details from VTOC's PT keyword value
+     *
+     * This API parses through VTOC's PT keyword value and returns the given
+     * record's offset, record's length, ECC offset and ECC length.
+     *
+     * @param[in] i_record - Record's name.
+     * @param[in] i_vtocOffset - Offset to VTOC record
+     *
+     * @return On success return record's details, on failure return empty
+     * buffer.
+     */
+    types::RecordData
+        getRecordDetailsFromVTOC(const types::Record& l_recordName,
+                                 const types::RecordOffset& i_vtocOffset);
+
+    /**
+     * @brief API to update record's ECC
+     *
+     * This API is required to update the record's ECC based on the record's
+     * current data.
+     *
+     * @param[in] i_recordDataOffset - Record's data offset
+     * @param[in] i_recordDataLength - Record's data length
+     * @param[in] i_recordECCOffset - Record's ECC offset
+     * @param[in] i_recordECCLength - Record's ECC length
+     * @param[in,out] io_vpdVector - FRU VPD in vector to update record's ECC.
+     *
+     * @throw EccException
+     */
+    void updateRecordECC(const auto& i_recordDataOffset,
+                         const auto& i_recordDataLength,
+                         const auto& i_recordECCOffset,
+                         size_t i_recordECCLength,
+                         types::BinaryVector& io_vpdVector);
+
+    /**
+     * @brief API to set record's keyword's value on hardware.
+     *
+     * @param[in] i_recordName - Record name.
+     * @param[in] i_keywordName - Keyword name.
+     * @param[in] i_keywordData - Keyword data.
+     * @param[in] i_recordDataOffset - Offset to record's data.
+     * @param[in,out] io_vpdVector - FRU VPD in vector to read and write
+     * keyword's value.
+     *
+     * @throw DataException
+     *
+     * @return On success returns number of bytes set. On failure returns -1.
+     */
+    int setKeywordValueInRecord(const types::Record& i_recordName,
+                                const types::Keyword& i_keywordName,
+                                const types::BinaryVector& i_keywordData,
+                                const types::RecordOffset& i_recordDataOffset,
+                                types::BinaryVector& io_vpdVector);
+
+    // Holds VPD data.
+    const types::BinaryVector& m_vpdVector;
+
+    // stores parsed VPD data.
+    types::IPZVpdMap m_parsedVPDMap{};
+
+    // Holds the VPD file path
+    const std::string& m_vpdFilePath;
+
+    // Stream to the VPD file. Required to correct ECC
+    std::fstream m_vpdFileStream;
+
+    // VPD start offset. Required for ECC correction.
+    size_t m_vpdStartOffset = 0;
+};
+} // namespace vpd
diff --git a/vpd-manager/include/isdimm_parser.hpp b/vpd-manager/include/isdimm_parser.hpp
new file mode 100644
index 0000000..091285c
--- /dev/null
+++ b/vpd-manager/include/isdimm_parser.hpp
@@ -0,0 +1,150 @@
+#pragma once
+
+#include "parser_interface.hpp"
+#include "types.hpp"
+
+#include <string_view>
+
+namespace vpd
+{
+/**
+ * @brief Concrete class to implement JEDEC SPD parsing.
+ *
+ * The class inherits ParserInterface interface class and overrides the parser
+ * functionality to implement parsing logic for JEDEC SPD format.
+ */
+class JedecSpdParser : public ParserInterface
+{
+  public:
+    // Deleted API's
+    JedecSpdParser() = delete;
+    JedecSpdParser(const JedecSpdParser&) = delete;
+    JedecSpdParser& operator=(const JedecSpdParser&) = delete;
+    JedecSpdParser(JedecSpdParser&&) = delete;
+    JedecSpdParser& operator=(JedecSpdParser&&) = delete;
+    ~JedecSpdParser() = default;
+
+    /**
+     * @brief Constructor
+     *
+     * @param[in] i_spdVector - JEDEC SPD data.
+     */
+    explicit JedecSpdParser(const types::BinaryVector& i_spdVector) :
+        m_memSpd(i_spdVector)
+    {}
+
+    /**
+     * @brief Parse the memory SPD binary data.
+     *
+     * Collects and emplace the keyword-value pairs in map.
+     *
+     * @return map of keyword:value
+     */
+    types::VPDMapVariant parse();
+
+  private:
+    /**
+     * @brief An API to read keywords.
+     *
+     * @param[in] i_iterator - iterator to buffer containing SPD
+     * @return- map of kwd:value
+     */
+    types::JedecSpdMap
+        readKeywords(types::BinaryVector::const_iterator& i_iterator);
+
+    /**
+     * @brief This function calculates DIMM size from DDR4 SPD
+     *
+     * @param[in] i_iterator - iterator to buffer containing SPD
+     * @return calculated size or 0 in case of any error.
+     */
+    auto getDDR4DimmCapacity(types::BinaryVector::const_iterator& i_iterator);
+
+    /**
+     * @brief This function calculates part number from DDR4 SPD
+     *
+     * @param[in] i_iterator - iterator to buffer containing SPD
+     * @return calculated part number or a default value.
+     */
+    std::string_view
+        getDDR4PartNumber(types::BinaryVector::const_iterator& i_iterator);
+
+    /**
+     * @brief This function calculates serial number from DDR4 SPD
+     *
+     * @param[in] i_iterator - iterator to buffer containing SPD
+     * @return calculated serial number or a default value.
+     */
+    std::string
+        getDDR4SerialNumber(types::BinaryVector::const_iterator& i_iterator);
+
+    /**
+     * @brief This function allocates FRU number based on part number
+     *
+     * Mappings for FRU number from calculated part number is used
+     * for DDR4 ISDIMM.
+     *
+     * @param[in] i_partNumber - part number of the DIMM
+     * @param[in] i_iterator - iterator to buffer containing SPD
+     * @return allocated FRU number or a default value
+     */
+    std::string_view
+        getDDR4FruNumber(const std::string& i_partNumber,
+                         types::BinaryVector::const_iterator& i_iterator);
+
+    /**
+     * @brief This function allocates CCIN based on part number for DDR4 SPD
+     *
+     * @param[in] i_partNumber - part number of the DIMM
+     * @return allocated CCIN or a default value.
+     */
+    std::string_view getDDR4CCIN(const std::string& i_partNumber);
+
+    /**
+     * @brief This function calculates DIMM size from DDR5 SPD
+     *
+     * @param[in] i_iterator - iterator to buffer containing SPD
+     * @return calculated size or 0 in case of any error.
+     */
+    auto getDDR5DimmCapacity(types::BinaryVector::const_iterator& i_iterator);
+
+    /**
+     * @brief This function calculates part number from DDR5 SPD
+     *
+     * @param[in] i_iterator - iterator to buffer containing SPD
+     * @return calculated part number or a default value.
+     */
+    auto getDDR5PartNumber(types::BinaryVector::const_iterator& i_iterator);
+
+    /**
+     * @brief This function calculates serial number from DDR5 SPD
+     *
+     * @param[in] i_iterator - iterator to buffer containing SPD
+     * @return calculated serial number.
+     */
+    auto getDDR5SerialNumber(types::BinaryVector::const_iterator& i_iterator);
+
+    /**
+     * @brief This function allocates FRU number based on part number
+     *
+     * Mappings for FRU number from calculated part number is used
+     * for DDR5 ISDIMM.
+     *
+     * @param[in] i_partNumber - part number of the DIMM
+     * @return allocated FRU number.
+     */
+    auto getDDR5FruNumber(const std::string& i_partNumber);
+
+    /**
+     * @brief This function allocates CCIN based on part number for DDR5 SPD
+     *
+     * @param[in] i_partNumber - part number of the DIMM
+     * @return allocated CCIN.
+     */
+    auto getDDR5CCIN(const std::string& i_partNumber);
+
+    // SPD file to be parsed
+    const types::BinaryVector& m_memSpd;
+};
+
+} // namespace vpd
diff --git a/vpd-manager/include/keyword_vpd_parser.hpp b/vpd-manager/include/keyword_vpd_parser.hpp
new file mode 100644
index 0000000..ae30a34
--- /dev/null
+++ b/vpd-manager/include/keyword_vpd_parser.hpp
@@ -0,0 +1,97 @@
+#pragma once
+
+#include "parser_interface.hpp"
+#include "types.hpp"
+
+namespace vpd
+{
+
+/**
+ * @brief Concrete class to implement Keyword VPD parsing
+ *
+ * The class inherits ParserInterface class and overrides the parser
+ * functionality to implement parsing logic for Keyword VPD format.
+ */
+class KeywordVpdParser : public ParserInterface
+{
+  public:
+    KeywordVpdParser() = delete;
+    KeywordVpdParser(const KeywordVpdParser&) = delete;
+    KeywordVpdParser(KeywordVpdParser&&) = delete;
+    ~KeywordVpdParser() = default;
+
+    /**
+     * @brief Constructor
+     *
+     * @param kwVpdVector - move it to object's m_keywordVpdVector
+     */
+    KeywordVpdParser(const types::BinaryVector& kwVpdVector) :
+        m_keywordVpdVector(kwVpdVector),
+        m_vpdIterator(m_keywordVpdVector.begin())
+    {}
+
+    /**
+     * @brief A wrapper function to parse the keyword VPD binary data.
+     *
+     * It validates certain tags and checksum data, calls helper function
+     * to parse and emplace the data as keyword-value pairs in KeywordVpdMap.
+     *
+     * @throw DataException - VPD is not valid
+     * @return map of keyword:value
+     */
+    types::VPDMapVariant parse();
+
+  private:
+    /**
+     * @brief Parse the VPD data and emplace them as pair into the Map.
+     *
+     * @throw DataException - VPD data size is 0, check VPD
+     * @return map of keyword:value
+     */
+    types::KeywordVpdMap populateVpdMap();
+
+    /**
+     * @brief Validate checksum.
+     *
+     * Finding the 2's complement of sum of all the
+     * keywords,values and large resource identifier string.
+     *
+     * @param[in] i_checkSumStart - VPD iterator pointing at checksum start
+     * value
+     * @param[in] i_checkSumEnd - VPD iterator pointing at checksum end value
+     * @throw DataException - checksum invalid, check VPD
+     */
+    void validateChecksum(types::BinaryVector::const_iterator i_checkSumStart,
+                          types::BinaryVector::const_iterator i_checkSumEnd);
+
+    /**
+     * @brief It reads 2 bytes from current VPD pointer
+     *
+     * @return 2 bytes of VPD data
+     */
+    inline size_t getKwDataSize()
+    {
+        return (*(m_vpdIterator + 1) << 8 | *m_vpdIterator);
+    }
+
+    /**
+     * @brief Check for given number of bytes validity
+     *
+     * Check if number of elements from (begining of the vector) to (iterator +
+     * numberOfBytes) is lesser than or equal to the total no.of elements in
+     * the vector. This check is performed before advancement of the iterator.
+     *
+     * @param[in] numberOfBytes - no.of positions the iterator is going to be
+     * iterated
+     *
+     * @throw DataException - Truncated VPD data, check VPD.
+     */
+    void checkNextBytesValidity(uint8_t numberOfBytes);
+
+    /*Vector of keyword VPD data*/
+    const types::BinaryVector& m_keywordVpdVector;
+
+    /*Iterator to VPD data*/
+    types::BinaryVector::const_iterator m_vpdIterator;
+};
+} // namespace vpd
diff --git a/vpd-manager/include/logger.hpp b/vpd-manager/include/logger.hpp
new file mode 100644
index 0000000..a4160c1
--- /dev/null
+++ b/vpd-manager/include/logger.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <iostream>
+#include <source_location>
+#include <string_view>
+
+namespace vpd
+{
+/**
+ * @brief The namespace defines logging related methods for VPD.
+ */
+namespace logging
+{
+
+/**
+ * @brief An api to log message.
+ * This API should be called to log message. It will auto append information
+ * like file name, line and function name to the message being logged.
+ *
+ * @param[in] message - Information that we want  to log.
+ * @param[in] location - Object of source_location class.
+ */
+void logMessage(std::string_view message, const std::source_location& location =
+                                              std::source_location::current());
+} // namespace logging
+} // namespace vpd
diff --git a/vpd-manager/include/manager.hpp b/vpd-manager/include/manager.hpp
new file mode 100644
index 0000000..cb64123
--- /dev/null
+++ b/vpd-manager/include/manager.hpp
@@ -0,0 +1,300 @@
+#pragma once
+
+#include "constants.hpp"
+#include "gpio_monitor.hpp"
+#include "types.hpp"
+#include "worker.hpp"
+
+#include <sdbusplus/asio/object_server.hpp>
+
+namespace vpd
+{
+/**
+ * @brief Class to manage VPD processing.
+ *
+ * The class is responsible to implement methods to manage VPD on the system.
+ * It also implements methods to be exposed over D-Bus required to access/edit
+ * VPD data.
+ */
+class Manager
+{
+  public:
+    /**
+     * List of deleted methods.
+     */
+    Manager(const Manager&) = delete;
+    Manager& operator=(const Manager&) = delete;
+    Manager(Manager&&) = delete;
+
+    /**
+     * @brief Constructor.
+     *
+     * @param[in] ioCon - IO context.
+     * @param[in] iFace - interface to implement.
+     * @param[in] connection - Dbus Connection.
+     */
+    Manager(const std::shared_ptr<boost::asio::io_context>& ioCon,
+            const std::shared_ptr<sdbusplus::asio::dbus_interface>& iFace,
+            const std::shared_ptr<sdbusplus::asio::connection>& asioConnection);
+
+    /**
+     * @brief Destructor.
+     */
+    ~Manager() = default;
+
+    /**
+     * @brief Update keyword value.
+     *
+     * This API is used to update keyword value on the given input path and its
+     * redundant path(s) if any taken from system config JSON.
+     *
+     * To update IPZ type VPD, input parameter for writing should be in the form
+     * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}).
+     *
+     * To update Keyword type VPD, input parameter for writing should be in the
+     * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}).
+     *
+     * @param[in] i_vpdPath - Path (inventory object path/FRU EEPROM path).
+     * @param[in] i_paramsToWriteData - Input details.
+     *
+     * @return On success returns number of bytes written, on failure returns
+     * -1.
+     */
+    int updateKeyword(const types::Path i_vpdPath,
+                      const types::WriteVpdParams i_paramsToWriteData);
+
+    /**
+     * @brief Update keyword value on hardware.
+     *
+     * This API is used to update keyword value on hardware. Updates only on the
+     * given input hardware path, does not look for corresponding redundant or
+     * primary path against the given path. To update corresponding paths, make
+     * separate call with respective path.
+     *
+     * To update IPZ type VPD, input parameter for writing should be in the form
+     * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}).
+     *
+     * To update Keyword type VPD, input parameter for writing should be in the
+     * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}).
+     *
+     * @param[in] i_fruPath - EEPROM path of the FRU.
+     * @param[in] i_paramsToWriteData - Input details.
+     *
+     * @return On success returns number of bytes written, on failure returns
+     * -1.
+     */
+    int updateKeywordOnHardware(
+        const types::Path i_fruPath,
+        const types::WriteVpdParams i_paramsToWriteData) noexcept;
+
+    /**
+     * @brief Read keyword value.
+     *
+     * API can be used to read VPD keyword from the given input path.
+     *
+     * To read keyword of type IPZ, input parameter for reading should be in the
+     * form of (Record, Keyword). Eg: ("VINI", "SN").
+     *
+     * To read keyword from keyword type VPD, just keyword name has to be
+     * supplied in the input parameter. Eg: ("SN").
+     *
+     * @param[in] i_fruPath - EEPROM path.
+     * @param[in] i_paramsToReadData - Input details.
+     *
+     * @throw
+     * sdbusplus::xyz::openbmc_project::Common::Device::Error::ReadFailure.
+     *
+     * @return On success returns the read value in variant of array of bytes.
+     * On failure throws exception.
+     */
+    types::DbusVariantType
+        readKeyword(const types::Path i_fruPath,
+                    const types::ReadVpdParams i_paramsToReadData);
+
+    /**
+     * @brief Collect single FRU VPD
+     * API can be used to perform VPD collection for the given FRU, only if the
+     * current state of the system matches with the state at which the FRU is
+     * allowed for VPD recollection.
+     *
+     * @param[in] i_dbusObjPath - D-bus object path
+     */
+    void collectSingleFruVpd(
+        const sdbusplus::message::object_path& i_dbusObjPath);
+
+    /**
+     * @brief Delete single FRU VPD
+     * API can be used to perform VPD deletion for the given FRU.
+     *
+     * @param[in] i_dbusObjPath - D-bus object path
+     */
+    void deleteSingleFruVpd(
+        const sdbusplus::message::object_path& i_dbusObjPath);
+
+    /**
+     * @brief Get expanded location code.
+     *
+     * API to get expanded location code from the unexpanded location code.
+     *
+     * @param[in] i_unexpandedLocationCode - Unexpanded location code.
+     * @param[in] i_nodeNumber - Denotes the node in case of a multi-node
+     * configuration, defaulted to zero incase of single node system.
+     *
+     * @throw xyz.openbmc_project.Common.Error.InvalidArgument for
+     * invalid argument.
+     *
+     * @return Location code of the FRU.
+     */
+    std::string getExpandedLocationCode(
+        const std::string& i_unexpandedLocationCode,
+        [[maybe_unused]] const uint16_t i_nodeNumber = 0);
+
+    /**
+     * @brief Get D-Bus object path of FRUs from expanded location code.
+     *
+     * An API to get list of FRU D-Bus object paths for a given expanded
+     * location code.
+     *
+     * @param[in] i_expandedLocationCode - Expanded location code.
+     *
+     * @throw xyz.openbmc_project.Common.Error.InvalidArgument for
+     * invalid argument.
+     *
+     * @return List of FRUs D-Bus object paths for the given location code.
+     */
+    types::ListOfPaths getFrusByExpandedLocationCode(
+        const std::string& i_expandedLocationCode);
+
+    /**
+     * @brief Get D-Bus object path of FRUs from unexpanded location code.
+     *
+     * An API to get list of FRU D-Bus object paths for a given unexpanded
+     * location code.
+     *
+     * @param[in] i_unexpandedLocationCode - Unexpanded location code.
+     * @param[in] i_nodeNumber - Denotes the node in case of a multi-node
+     * configuration, defaulted to zero incase of single node system.
+     *
+     * @throw xyz.openbmc_project.Common.Error.InvalidArgument for
+     * invalid argument.
+     *
+     * @return List of FRUs D-Bus object paths for the given location code.
+     */
+    types::ListOfPaths getFrusByUnexpandedLocationCode(
+        const std::string& i_unexpandedLocationCode,
+        [[maybe_unused]] const uint16_t i_nodeNumber = 0);
+
+    /**
+     * @brief Get Hardware path
+     * API can be used to get EEPROM path for the given inventory path.
+     *
+     * @param[in] i_dbusObjPath - D-bus object path
+     *
+     * @return Corresponding EEPROM path.
+     */
+    std::string getHwPath(const sdbusplus::message::object_path& i_dbusObjPath);
+
+    /**
+     * @brief  Perform VPD recollection
+     * This api will trigger parser to perform VPD recollection for FRUs that
+     * can be replaced at standby.
+     */
+    void performVpdRecollection();
+
+    /**
+     * @brief Get unexpanded location code.
+     *
+     * An API to get unexpanded location code and node number from expanded
+     * location code.
+     *
+     * @param[in] i_expandedLocationCode - Expanded location code.
+     *
+     * @throw xyz.openbmc_project.Common.Error.InvalidArgument for
+     * invalid argument.
+     *
+     * @return Location code in unexpanded format and its node number.
+     */
+    std::tuple<std::string, uint16_t>
+        getUnexpandedLocationCode(const std::string& i_expandedLocationCode);
+
+  private:
+#ifdef IBM_SYSTEM
+    /**
+     * @brief API to set timer to detect system VPD over D-Bus.
+     *
+     * System VPD is required before bus name for VPD-Manager is claimed. Once
+     * system VPD is published, VPD for other FRUs should be collected. This API
+     * detects id system VPD is already published on D-Bus and based on that
+     * triggers VPD collection for rest of the FRUs.
+     *
+     * Note: Throws exception in case of any failure. Needs to be handled by the
+     * caller.
+     */
+    void SetTimerToDetectSVPDOnDbus();
+
+    /**
+     * @brief Set timer to detect and set VPD collection status for the system.
+     *
+     * Collection of FRU VPD is triggered in a separate thread. Resulting in
+     * multiple threads at  a given time. The API creates a timer which on
+     * regular interval will check if all the threads were collected back and
+     * sets the status of the VPD collection for the system accordingly.
+     *
+     * @throw std::runtime_error
+     */
+    void SetTimerToDetectVpdCollectionStatus();
+
+    /**
+     * @brief API to register callback for "AssetTag" property change.
+     */
+    void registerAssetTagChangeCallback();
+
+    /**
+     * @brief Callback API to be triggered on "AssetTag" property change.
+     *
+     * @param[in] i_msg - The callback message.
+     */
+    void processAssetTagChangeCallback(sdbusplus::message_t& i_msg);
+#endif
+
+    /**
+     * @brief An api to check validity of unexpanded location code.
+     *
+     * @param[in] i_locationCode - Unexpanded location code.
+     *
+     * @return True/False based on validity check.
+     */
+    bool isValidUnexpandedLocationCode(const std::string& i_locationCode);
+
+    /**
+     * @brief API to register callback for Host state change.
+     */
+    void registerHostStateChangeCallback();
+
+    /**
+     * @brief API to process host state change callback.
+     *
+     * @param[in] i_msg - Callback message.
+     */
+    void hostStateChangeCallBack(sdbusplus::message_t& i_msg);
+
+    // Shared pointer to asio context object.
+    const std::shared_ptr<boost::asio::io_context>& m_ioContext;
+
+    // Shared pointer to Dbus interface class.
+    const std::shared_ptr<sdbusplus::asio::dbus_interface>& m_interface;
+
+    // Shared pointer to bus connection.
+    const std::shared_ptr<sdbusplus::asio::connection>& m_asioConnection;
+
+    // Shared pointer to worker class
+    std::shared_ptr<Worker> m_worker;
+
+    // Shared pointer to GpioMonitor class
+    std::shared_ptr<GpioMonitor> m_gpioMonitor;
+
+    // Variable to hold current collection status
+    std::string m_vpdCollectionStatus = "NotStarted";
+};
+
+} // namespace vpd
diff --git a/vpd-manager/include/parser.hpp b/vpd-manager/include/parser.hpp
new file mode 100644
index 0000000..9af3088
--- /dev/null
+++ b/vpd-manager/include/parser.hpp
@@ -0,0 +1,126 @@
+#pragma once
+
+#include "parser_factory.hpp"
+#include "parser_interface.hpp"
+#include "types.hpp"
+
+#include <string.h>
+
+#include <nlohmann/json.hpp>
+
+#include <iostream>
+
+namespace vpd
+{
+/**
+ * @brief Class to implement a wrapper around concrete parser class.
+ * The class based on VPD file passed, selects the required parser and exposes
+ * API to parse the VPD and return the parsed data in required format to the
+ * caller.
+ */
+class Parser
+{
+  public:
+    /**
+     * @brief Constructor
+     *
+     * @param[in] vpdFilePath - Path to the VPD file.
+     * @param[in] parsedJson - Parsed JSON.
+     */
+    Parser(const std::string& vpdFilePath, nlohmann::json parsedJson);
+
+    /**
+     * @brief API to implement a generic parsing logic.
+     *
+     * This API is called to select parser based on the vpd data extracted from
+     * the VPD file path passed to the constructor of the class.
+     * It further parses the data based on the parser selected and returned
+     * parsed map to the caller.
+     */
+    types::VPDMapVariant parse();
+
+    /**
+     * @brief API to get parser instance based on VPD type.
+     *
+     * This API detects the VPD type based on the file path passed to the
+     * constructor of the class and returns the respective parser instance.
+     *
+     * @return Parser instance.
+     */
+    std::shared_ptr<vpd::ParserInterface> getVpdParserInstance();
+
+    /**
+     * @brief Update keyword value.
+     *
+     * This API is used to update keyword value on the EEPROM path and its
+     * redundant path(s) if any taken from system config JSON. And also updates
+     * keyword value on DBus.
+     *
+     * To update IPZ type VPD, input parameter for writing should be in the form
+     * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}).
+     *
+     * To update Keyword type VPD, input parameter for writing should be in the
+     * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}).
+     *
+     * @param[in] i_paramsToWriteData - Input details.
+     *
+     * @return On success returns number of bytes written, on failure returns
+     * -1.
+     */
+    int updateVpdKeyword(const types::WriteVpdParams& i_paramsToWriteData);
+
+    /**
+     * @brief Update keyword value on hardware.
+     *
+     * This API is used to update keyword value on the hardware path.
+     *
+     * To update IPZ type VPD, input parameter for writing should be in the form
+     * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}).
+     *
+     * To update Keyword type VPD, input parameter for writing should be in the
+     * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}).
+     *
+     * @param[in] i_paramsToWriteData - Input details.
+     *
+     * @return On success returns number of bytes written, on failure returns
+     * -1.
+     */
+    int updateVpdKeywordOnHardware(
+        const types::WriteVpdParams& i_paramsToWriteData);
+
+  private:
+    /**
+     * @brief Update keyword value on redundant path.
+     *
+     * This API is used to update keyword value on the given redundant path(s).
+     *
+     * To update IPZ type VPD, input parameter for writing should be in the form
+     * of (Record, Keyword, Value). Eg: ("VINI", "SN", {0x01, 0x02, 0x03}).
+     *
+     * To update Keyword type VPD, input parameter for writing should be in the
+     * form of (Keyword, Value). Eg: ("PE", {0x01, 0x02, 0x03}).
+     *
+     * @param[in] i_fruPath - Redundant EEPROM path.
+     * @param[in] i_paramsToWriteData - Input details.
+     *
+     * @return On success returns number of bytes written, on failure returns
+     * -1.
+     */
+    int updateVpdKeywordOnRedundantPath(
+        const std::string& i_fruPath,
+        const types::WriteVpdParams& i_paramsToWriteData);
+
+    // holds offfset to VPD if applicable.
+    size_t m_vpdStartOffset = 0;
+
+    // Path to the VPD file
+    const std::string& m_vpdFilePath;
+
+    // Path to configuration file, can be empty.
+    nlohmann::json m_parsedJson;
+
+    // Vector to hold VPD.
+    types::BinaryVector m_vpdVector;
+
+}; // parser
+} // namespace vpd
diff --git a/vpd-manager/include/parser_factory.hpp b/vpd-manager/include/parser_factory.hpp
new file mode 100644
index 0000000..819ec59
--- /dev/null
+++ b/vpd-manager/include/parser_factory.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "logger.hpp"
+#include "parser_interface.hpp"
+#include "types.hpp"
+
+#include <memory>
+
+namespace vpd
+{
+/**
+ * @brief Factory calss to instantiate concrete parser class.
+ *
+ * This class should be used to instantiate an instance of parser class based
+ * on the type of vpd file.
+ */
+class ParserFactory
+{
+  public:
+    // Deleted APIs
+    ParserFactory() = delete;
+    ~ParserFactory() = delete;
+    ParserFactory(const ParserFactory&) = delete;
+    ParserFactory& operator=(const ParserFactory&) = delete;
+    ParserFactory(ParserFactory&&) = delete;
+    ParserFactory& operator=(ParserFactory&&) = delete;
+
+    /**
+     * @brief An API to get object of concrete parser class.
+     *
+     * The method is used to get object of respective parser class based on the
+     * type of VPD extracted from VPD vector passed to the API.
+     * To detect respective parser from VPD vector, add logic into the API
+     * vpdTypeCheck.
+     *
+     * Note: API throws DataException in case vpd type check fails for any
+     * unknown type. Caller responsibility to handle the exception.
+     *
+     * @param[in] i_vpdVector - vpd file content to check for the type.
+     * @param[in] i_vpdFilePath - FRU EEPROM path.
+     * @param[in] i_vpdStartOffset - Offset from where VPD starts in the VPD
+     * file.
+     *
+     * @return - Pointer to concrete parser class object.
+     */
+    static std::shared_ptr<ParserInterface>
+        getParser(const types::BinaryVector& i_vpdVector,
+                  const std::string& i_vpdFilePath, size_t i_vpdStartOffset);
+};
+} // namespace vpd
diff --git a/vpd-manager/include/parser_interface.hpp b/vpd-manager/include/parser_interface.hpp
new file mode 100644
index 0000000..0ff2862
--- /dev/null
+++ b/vpd-manager/include/parser_interface.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include "types.hpp"
+
+#include <variant>
+
+namespace vpd
+{
+/**
+ * @brief Interface class for parsers.
+ *
+ * Any concrete parser class, implementing parsing logic need to derive from
+ * this interface class and override the parse method declared in this class.
+ */
+class ParserInterface
+{
+  public:
+    /**
+     * @brief Pure virtual function for parsing VPD file.
+     *
+     * The API needs to be overridden by all the classes deriving from parser
+     * inerface class to implement respective VPD parsing logic.
+     *
+     * @return parsed format for VPD data, depending upon the
+     * parsing logic.
+     */
+    virtual types::VPDMapVariant parse() = 0;
+
+    /**
+     * @brief Read keyword's value from hardware
+     *
+     * @param[in] types::ReadVpdParams - Parameters required to perform read.
+     *
+     * @return keyword's value on successful read. Exception on failure.
+     */
+    virtual types::DbusVariantType
+        readKeywordFromHardware(const types::ReadVpdParams)
+    {
+        return types::DbusVariantType();
+    }
+
+    /**
+     * @brief API to write keyword's value on hardware.
+     *
+     * This virtual method is created to achieve runtime polymorphism for
+     * hardware writes on VPD of different types. This virtual method can be
+     * redefined at derived classess to implement write according to the type of
+     * VPD.
+     *
+     * @param[in] i_paramsToWriteData - Data required to perform write.
+     *
+     * @throw May throw exception depending on the implementation of derived
+     * methods.
+     * @return On success returns number of bytes written on hardware, On
+     * failure returns -1.
+     */
+    virtual int
+        writeKeywordOnHardware(const types::WriteVpdParams i_paramsToWriteData)
+    {
+        (void)i_paramsToWriteData;
+        return -1;
+    }
+
+    /**
+     * @brief Virtual destructor.
+     */
+    virtual ~ParserInterface() {}
+};
+} // namespace vpd
diff --git a/vpd-manager/include/types.hpp b/vpd-manager/include/types.hpp
new file mode 100644
index 0000000..314aebd
--- /dev/null
+++ b/vpd-manager/include/types.hpp
@@ -0,0 +1,192 @@
+#pragma once
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <sdbusplus/asio/property.hpp>
+#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/Common/Device/error.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <tuple>
+#include <unordered_map>
+#include <variant>
+
+namespace vpd
+{
+namespace types
+{
+
+using BiosProperty = std::tuple<
+    std::string, bool, std::string, std::string, std::string,
+    std::variant<int64_t, std::string>, std::variant<int64_t, std::string>,
+    std::vector<std::tuple<std::string, std::variant<int64_t, std::string>,
+                           std::string>>>;
+using BiosBaseTable =
+    std::variant<std::monostate, std::map<std::string, BiosProperty>>;
+using BiosBaseTableType = std::map<std::string, BiosBaseTable>;
+using BiosAttributeCurrentValue =
+    std::variant<std::monostate, int64_t, std::string>;
+using BiosAttributePendingValue = std::variant<int64_t, std::string>;
+using BiosGetAttrRetType = std::tuple<std::string, BiosAttributeCurrentValue,
+                                      BiosAttributePendingValue>;
+using PendingBIOSAttrItem =
+    std::pair<std::string, std::tuple<std::string, BiosAttributePendingValue>>;
+using PendingBIOSAttrs = std::vector<PendingBIOSAttrItem>;
+
+using BinaryVector = std::vector<uint8_t>;
+
+// This covers mostly all the data type supported over Dbus for a property.
+// clang-format off
+using DbusVariantType = std::variant<
+    std::vector<std::tuple<std::string, std::string, std::string>>,
+    std::vector<std::string>,
+    std::vector<double>,
+    std::string,
+    int64_t,
+    uint64_t,
+    double,
+    int32_t,
+    uint32_t,
+    int16_t,
+    uint16_t,
+    uint8_t,
+    bool,
+    BinaryVector,
+    std::vector<uint32_t>,
+    std::vector<uint16_t>,
+    sdbusplus::message::object_path,
+    std::tuple<uint64_t, std::vector<std::tuple<std::string, std::string, double, uint64_t>>>,
+    std::vector<std::tuple<std::string, std::string>>,
+    std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>,
+    std::vector<std::tuple<uint32_t, size_t>>,
+    std::vector<std::tuple<sdbusplus::message::object_path, std::string,
+                           std::string, std::string>>,
+    PendingBIOSAttrs
+ >;
+
+using MapperGetObject =
+    std::vector<std::pair<std::string, std::vector<std::string>>>;
+using MapperGetSubTree = std::map<std::string, std::map<std::string, std::vector<std::string>>>;
+
+/* A type for holding the innermost map of property::value.*/
+using IPZKwdValueMap = std::unordered_map<std::string, std::string>;
+/*IPZ VPD Map of format <Record name, <keyword, value>>*/
+using IPZVpdMap = std::unordered_map<std::string, IPZKwdValueMap>;
+
+/*Value types supported by Keyword VPD*/
+using KWdVPDValueType = std::variant<BinaryVector,std::string, size_t>;
+/* This hold map of parsed data of keyword VPD type*/
+using KeywordVpdMap = std::unordered_map<std::string, KWdVPDValueType>;
+
+/**
+ * Both Keyword VPD parser and DDIMM parser stores the
+ * parsed VPD in the same format.
+ * To have better readability, two types are defined for underneath data structure.
+*/
+using DdimmVpdMap = KeywordVpdMap;
+
+/**
+ * Both Keyword VPD parser and ISDIMM parser stores the
+ * parsed SPD in the same format.
+*/
+using JedecSpdMap = KeywordVpdMap;
+
+/**
+ * Type to hold keyword::value map of a VPD.
+ * Variant can be extended to support additional type.
+*/
+using VPDKWdValueMap = std::variant<IPZKwdValueMap, KeywordVpdMap>;
+
+/* Map<Property, Value>*/
+using PropertyMap = std::map<std::string, DbusVariantType>;
+/* Map<Interface<Property, Value>>*/
+using InterfaceMap = std::map<std::string, PropertyMap>;
+using ObjectMap = std::map<sdbusplus::message::object_path, InterfaceMap>;
+
+using KwSize = uint8_t;
+using RecordId = uint8_t;
+using RecordSize = uint16_t;
+using RecordType = uint16_t;
+using RecordOffset = uint16_t;
+using RecordLength = uint16_t;
+using ECCOffset = uint16_t;
+using ECCLength = uint16_t;
+using PoundKwSize = uint16_t;
+
+using RecordOffsetList = std::vector<uint32_t>;
+
+using VPDMapVariant = std::variant<std::monostate, IPZVpdMap, KeywordVpdMap>;
+
+using HWVerList = std::vector<std::pair<std::string, std::string>>;
+/**
+ * Map of <systemIM, pair<Default version, vector<HW version, JSON suffix>>>
+*/
+using SystemTypeMap =
+    std::unordered_map<std::string, std::pair<std::string, HWVerList>>;
+
+using Path = std::string;
+using Record = std::string;
+using Keyword = std::string;
+
+using IpzData = std::tuple<Record, Keyword, BinaryVector>;
+using KwData = std::tuple<Keyword, BinaryVector>;
+using VpdData = std::variant<IpzData, KwData>;
+
+using IpzType = std::tuple<Record, Keyword>;
+using ReadVpdParams = std::variant<IpzType, Keyword>;
+using WriteVpdParams = std::variant<IpzData, KwData>;
+
+using ListOfPaths = std::vector<sdbusplus::message::object_path>;
+using RecordData = std::tuple<RecordOffset, RecordLength, ECCOffset, ECCLength>;
+
+using DbusInvalidArgument =
+    sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
+using DbusNotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
+
+using InvalidArgument = phosphor::logging::xyz::openbmc_project::Common::InvalidArgument;
+
+namespace DeviceError = sdbusplus::xyz::openbmc_project::Common::Device::Error;
+
+/* PEL Severity enum as defined in [xyz.openbmc_project.Logging.Entry.Level]log.hpp from 'phosphor-logging' repo. */
+enum SeverityType
+{
+    Notice,
+    Informational,
+    Debug,
+    Warning,
+    Critical,
+    Emergency,
+    Alert,
+    Error
+};
+
+/* PEL callout priority from 'phosphor-logging' pel_types.hpp. If any change in 'phosphor-logging', it needs update here as well. */
+enum CalloutPriority
+{
+    High,
+    Medium,
+    MediumGroupA,
+    MediumGroupB,
+    MediumGroupC,
+    Low
+};
+
+/* The Message property of the event entry for creating PEL, to introduce new message needs to be added in 'phosphor-logging' message_registry.json as well. */
+enum ErrorType
+{
+    DefaultValue,
+    InvalidVpdMessage,
+    VpdMismatch,
+    InvalidEeprom,
+    EccCheckFailed,
+    JsonFailure,
+    DbusFailure,
+    InvalidSystem,
+    EssentialFru,
+    GpioError
+};
+
+using InventoryCalloutData = std::tuple<std::string, CalloutPriority>;
+using DeviceCalloutData = std::tuple<std::string, std::string>;
+using I2cBusCalloutData = std::tuple<std::string, std::string, std::string>;
+} // namespace types
+} // namespace vpd
diff --git a/vpd-manager/include/utility/common_utility.hpp b/vpd-manager/include/utility/common_utility.hpp
new file mode 100644
index 0000000..15b33a2
--- /dev/null
+++ b/vpd-manager/include/utility/common_utility.hpp
@@ -0,0 +1,117 @@
+#pragma once
+
+#include "constants.hpp"
+#include "logger.hpp"
+
+#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+/**
+ * @brief Namespace to host common utility methods.
+ *
+ * A method qualifies as a common utility function if,
+ * A)It is being used by the utility namespace at the same level as well as
+ * other files directly.
+ * B) The utility should be a leaf node and should not be dependent on any other
+ * utility.
+ *                  *******************
+ *                  | Commmon Utility | - - - - - - -
+ *                  *******************              |
+ *                          /\                       |
+ *                         /  \                      |
+ *         ****************    ****************      |
+ *         | json utility |    | dbus utility |      |
+ *         ****************    ****************      |
+ *                 \                 /               |
+ *                  \               /                |
+ *               ************************            |
+ *               | Vpd specific Utility | - - - - - - -
+ *               ************************
+ */
+
+namespace vpd
+{
+
+namespace commonUtility
+{
+/** @brief Return the hex representation of the incoming byte.
+ *
+ * @param [in] i_aByte - The input byte.
+ * @returns Hex representation of the byte as a character.
+ */
+constexpr auto toHex(size_t i_aByte)
+{
+    constexpr auto l_map = "0123456789abcdef";
+    return l_map[i_aByte];
+}
+
+/**
+ * @brief API to return null at the end of variadic template args.
+ *
+ * @return empty string.
+ */
+inline std::string getCommand()
+{
+    return "";
+}
+
+/**
+ * @brief API to arrange create command.
+ *
+ * @param[in] arguments to create the command
+ * @return Command string
+ */
+template <typename T, typename... Types>
+inline std::string getCommand(T i_arg1, Types... i_args)
+{
+    std::string l_cmd = " " + i_arg1 + getCommand(i_args...);
+
+    return l_cmd;
+}
+
+/**
+ * @brief API to create shell command and execute.
+ *
+ * @throw std::runtime_error.
+ *
+ * @param[in] arguments for command
+ * @returns output of that command
+ */
+template <typename T, typename... Types>
+inline std::vector<std::string> executeCmd(T&& i_path, Types... i_args)
+{
+    std::vector<std::string> l_cmdOutput;
+    std::array<char, constants::CMD_BUFFER_LENGTH> l_buffer;
+
+    std::string l_cmd = i_path + getCommand(i_args...);
+
+    std::unique_ptr<FILE, decltype(&pclose)> l_cmdPipe(
+        popen(l_cmd.c_str(), "r"), pclose);
+
+    if (!l_cmdPipe)
+    {
+        logging::logMessage(
+            "popen failed with error " + std::string(strerror(errno)));
+        throw std::runtime_error("popen failed!");
+    }
+    while (fgets(l_buffer.data(), l_buffer.size(), l_cmdPipe.get()) != nullptr)
+    {
+        l_cmdOutput.emplace_back(l_buffer.data());
+    }
+
+    return l_cmdOutput;
+}
+
+/** @brief Converts string to lower case.
+ *
+ * @param [in] i_string - Input string.
+ */
+inline void toLower(std::string& i_string)
+{
+    std::transform(i_string.begin(), i_string.end(), i_string.begin(),
+                   [](unsigned char l_char) { return std::tolower(l_char); });
+}
+} // namespace commonUtility
+} // namespace vpd
diff --git a/vpd-manager/include/utility/dbus_utility.hpp b/vpd-manager/include/utility/dbus_utility.hpp
new file mode 100644
index 0000000..4c81815
--- /dev/null
+++ b/vpd-manager/include/utility/dbus_utility.hpp
@@ -0,0 +1,567 @@
+#pragma once
+
+#include "constants.hpp"
+#include "logger.hpp"
+#include "types.hpp"
+
+#include <chrono>
+
+namespace vpd
+{
+/**
+ * @brief The namespace defines utlity methods for generic D-Bus operations.
+ */
+namespace dbusUtility
+{
+
+/**
+ * @brief An API to get Map of service and interfaces for an object path.
+ *
+ * The API returns a Map of service name and interfaces for a given pair of
+ * object path and interface list. It can be used to determine service name
+ * which implemets a particular object path and interface.
+ *
+ * Note: It will be caller's responsibility to check for empty map returned and
+ * generate appropriate error.
+ *
+ * @param [in] objectPath - Object path under the service.
+ * @param [in] interfaces - Array of interface(s).
+ * @return - A Map of service name to object to interface(s), if success.
+ *           If failed,  empty map.
+ */
+inline types::MapperGetObject getObjectMap(const std::string& objectPath,
+                                           std::span<const char*> interfaces)
+{
+    types::MapperGetObject getObjectMap;
+
+    // interface list is optional argument, hence no check required.
+    if (objectPath.empty())
+    {
+        logging::logMessage("Path value is empty, invalid call to GetObject");
+        return getObjectMap;
+    }
+
+    try
+    {
+        auto bus = sdbusplus::bus::new_default();
+        auto method = bus.new_method_call(
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetObject");
+
+        method.append(objectPath, interfaces);
+        auto result = bus.call(method);
+        result.read(getObjectMap);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        // logging::logMessage(e.what());
+        return getObjectMap;
+    }
+
+    return getObjectMap;
+}
+
+/**
+ * @brief An API to get property map for an interface.
+ *
+ * This API returns a map of property and its value with respect to a particular
+ * interface.
+ *
+ * Note: It will be caller's responsibility to check for empty map returned and
+ * generate appropriate error.
+ *
+ * @param[in] i_service - Service name.
+ * @param[in] i_objectPath - object path.
+ * @param[in] i_interface - Interface, for the properties to be listed.
+ *
+ * @return - A map of property and value of an interface, if success.
+ *           if failed, empty map.
+ */
+inline types::PropertyMap getPropertyMap(const std::string& i_service,
+                                         const std::string& i_objectPath,
+                                         const std::string& i_interface)
+{
+    types::PropertyMap l_propertyValueMap;
+    if (i_service.empty() || i_objectPath.empty() || i_interface.empty())
+    {
+        logging::logMessage("Invalid parameters to get property map");
+        return l_propertyValueMap;
+    }
+
+    try
+    {
+        auto l_bus = sdbusplus::bus::new_default();
+        auto l_method =
+            l_bus.new_method_call(i_service.c_str(), i_objectPath.c_str(),
+                                  "org.freedesktop.DBus.Properties", "GetAll");
+        l_method.append(i_interface);
+        auto l_result = l_bus.call(l_method);
+        l_result.read(l_propertyValueMap);
+    }
+    catch (const sdbusplus::exception::SdBusError& l_ex)
+    {
+        logging::logMessage(l_ex.what());
+    }
+
+    return l_propertyValueMap;
+}
+
+/**
+ * @brief API to get object subtree from D-bus.
+ *
+ * The API returns the map of object, services and interfaces in the
+ * subtree that implement a certain interface. If no interfaces are provided
+ * then all the objects, services and interfaces under the subtree will
+ * be returned.
+ *
+ * Note: Depth can be 0 and interfaces can be null.
+ * It will be caller's responsibility to check for empty vector returned
+ * and generate appropriate error.
+ *
+ * @param[in] i_objectPath - Path to search for an interface.
+ * @param[in] i_depth - Maximum depth of the tree to search.
+ * @param[in] i_interfaces - List of interfaces to search.
+ *
+ * @return - A map of object and its related services and interfaces, if
+ *           success. If failed, empty map.
+ */
+
+inline types::MapperGetSubTree
+    getObjectSubTree(const std::string& i_objectPath, const int& i_depth,
+                     const std::vector<std::string>& i_interfaces)
+{
+    types::MapperGetSubTree l_subTreeMap;
+
+    if (i_objectPath.empty())
+    {
+        logging::logMessage("Object path is empty.");
+        return l_subTreeMap;
+    }
+
+    try
+    {
+        auto l_bus = sdbusplus::bus::new_default();
+        auto l_method = l_bus.new_method_call(
+            constants::objectMapperService, constants::objectMapperPath,
+            constants::objectMapperInf, "GetSubTree");
+        l_method.append(i_objectPath, i_depth, i_interfaces);
+        auto l_result = l_bus.call(l_method);
+        l_result.read(l_subTreeMap);
+    }
+    catch (const sdbusplus::exception::SdBusError& l_ex)
+    {
+        logging::logMessage(l_ex.what());
+    }
+
+    return l_subTreeMap;
+}
+
+/**
+ * @brief An API to read property from Dbus.
+ *
+ * The caller of the API needs to validate the validatity and correctness of the
+ * type and value of data returned. The API will just fetch and retun the data
+ * without any data validation.
+ *
+ * Note: It will be caller's responsibility to check for empty value returned
+ * and generate appropriate error if required.
+ *
+ * @param [in] serviceName - Name of the Dbus service.
+ * @param [in] objectPath - Object path under the service.
+ * @param [in] interface - Interface under which property exist.
+ * @param [in] property - Property whose value is to be read.
+ * @return - Value read from Dbus, if success.
+ *           If failed, empty variant.
+ */
+inline types::DbusVariantType readDbusProperty(
+    const std::string& serviceName, const std::string& objectPath,
+    const std::string& interface, const std::string& property)
+{
+    types::DbusVariantType propertyValue;
+
+    // Mandatory fields to make a read dbus call.
+    if (serviceName.empty() || objectPath.empty() || interface.empty() ||
+        property.empty())
+    {
+        logging::logMessage(
+            "One of the parameter to make Dbus read call is empty.");
+        return propertyValue;
+    }
+
+    try
+    {
+        auto bus = sdbusplus::bus::new_default();
+        auto method =
+            bus.new_method_call(serviceName.c_str(), objectPath.c_str(),
+                                "org.freedesktop.DBus.Properties", "Get");
+        method.append(interface, property);
+
+        auto result = bus.call(method);
+        result.read(propertyValue);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        return propertyValue;
+    }
+    return propertyValue;
+}
+
+/**
+ * @brief An API to write property on Dbus.
+ *
+ * The caller of this API needs to handle exception thrown by this method to
+ * identify any write failure. The API in no other way indicate write  failure
+ * to the caller.
+ *
+ * Note: It will be caller's responsibility ho handle the exception thrown in
+ * case of write failure and generate appropriate error.
+ *
+ * @param [in] serviceName - Name of the Dbus service.
+ * @param [in] objectPath - Object path under the service.
+ * @param [in] interface - Interface under which property exist.
+ * @param [in] property - Property whose value is to be written.
+ * @param [in] propertyValue - The value to be written.
+ */
+inline void writeDbusProperty(
+    const std::string& serviceName, const std::string& objectPath,
+    const std::string& interface, const std::string& property,
+    const types::DbusVariantType& propertyValue)
+{
+    // Mandatory fields to make a write dbus call.
+    if (serviceName.empty() || objectPath.empty() || interface.empty() ||
+        property.empty())
+    {
+        logging::logMessage(
+            "One of the parameter to make Dbus read call is empty.");
+
+        // caller need to handle the throw to ensure Dbus write success.
+        throw std::runtime_error("Dbus write failed, Parameter empty");
+    }
+
+    try
+    {
+        auto bus = sdbusplus::bus::new_default();
+        auto method =
+            bus.new_method_call(serviceName.c_str(), objectPath.c_str(),
+                                "org.freedesktop.DBus.Properties", "Set");
+        method.append(interface, property, propertyValue);
+        bus.call(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        logging::logMessage(e.what());
+
+        // caller needs to handle this throw to handle error in writing Dbus.
+        throw std::runtime_error("Dbus write failed");
+    }
+}
+
+/**
+ * @brief API to publish data on PIM
+ *
+ * The API calls notify on PIM object to publlish VPD.
+ *
+ * @param[in] objectMap - Object, its interface and data.
+ * @return bool - Status of call to PIM notify.
+ */
+inline bool callPIM(types::ObjectMap&& objectMap)
+{
+    try
+    {
+        for (const auto& l_objectKeyValue : objectMap)
+        {
+            auto l_nodeHandle = objectMap.extract(l_objectKeyValue.first);
+
+            if (l_nodeHandle.key().str.find(constants::pimPath, 0) !=
+                std::string::npos)
+            {
+                l_nodeHandle.key() = l_nodeHandle.key().str.replace(
+                    0, std::strlen(constants::pimPath), "");
+                objectMap.insert(std::move(l_nodeHandle));
+            }
+        }
+
+        auto bus = sdbusplus::bus::new_default();
+        auto pimMsg =
+            bus.new_method_call(constants::pimServiceName, constants::pimPath,
+                                constants::pimIntf, "Notify");
+        pimMsg.append(std::move(objectMap));
+        bus.call(pimMsg);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        return false;
+    }
+    return true;
+}
+
+/**
+ * @brief API to check if a D-Bus service is running or not.
+ *
+ * Any failure in calling the method "NameHasOwner" implies that the service is
+ * not in a running state. Hence the API returns false in case of any exception
+ * as well.
+ *
+ * @param[in] i_serviceName - D-Bus service name whose status is to be checked.
+ * @return bool - True if the service is running, false otherwise.
+ */
+inline bool isServiceRunning(const std::string& i_serviceName)
+{
+    bool l_retVal = false;
+
+    try
+    {
+        auto l_bus = sdbusplus::bus::new_default();
+        auto l_method = l_bus.new_method_call(
+            "org.freedesktop.DBus", "/org/freedesktop/DBus",
+            "org.freedesktop.DBus", "NameHasOwner");
+        l_method.append(i_serviceName);
+
+        l_bus.call(l_method).read(l_retVal);
+    }
+    catch (const sdbusplus::exception::SdBusError& l_ex)
+    {
+        logging::logMessage(
+            "Call to check service status failed with exception: " +
+            std::string(l_ex.what()));
+    }
+
+    return l_retVal;
+}
+
+/**
+ * @brief API to call "GetAttribute" method uner BIOS manager.
+ *
+ * The API reads the given attribuute from BIOS and returns a tuple of both
+ * current as well as pending value for that attribute.
+ * The API return only the current attribute value if found.
+ * API returns an empty variant of type BiosAttributeCurrentValue in case of any
+ * error.
+ *
+ * @param[in] i_attributeName - Attribute to be read.
+ * @return Tuple of PLDM attribute Type, current attribute value and pending
+ * attribute value.
+ */
+inline types::BiosAttributeCurrentValue
+    biosGetAttributeMethodCall(const std::string& i_attributeName)
+{
+    auto l_bus = sdbusplus::bus::new_default();
+    auto l_method = l_bus.new_method_call(
+        constants::biosConfigMgrService, constants::biosConfigMgrObjPath,
+        constants::biosConfigMgrInterface, "GetAttribute");
+    l_method.append(i_attributeName);
+
+    types::BiosGetAttrRetType l_attributeVal;
+    try
+    {
+        auto l_result = l_bus.call(l_method);
+        l_result.read(std::get<0>(l_attributeVal), std::get<1>(l_attributeVal),
+                      std::get<2>(l_attributeVal));
+    }
+    catch (const sdbusplus::exception::SdBusError& l_ex)
+    {
+        logging::logMessage(
+            "Failed to read BIOS Attribute: " + i_attributeName +
+            " due to error " + std::string(l_ex.what()));
+
+        // TODO: Log an informational PEL here.
+    }
+
+    return std::get<1>(l_attributeVal);
+}
+
+/**
+ * @brief API to check if Chassis is powered on.
+ *
+ * This API queries Phosphor Chassis State Manager to know whether
+ * Chassis is powered on.
+ *
+ * @return true if chassis is powered on, false otherwise
+ */
+inline bool isChassisPowerOn()
+{
+    auto powerState = dbusUtility::readDbusProperty(
+        "xyz.openbmc_project.State.Chassis",
+        "/xyz/openbmc_project/state/chassis0",
+        "xyz.openbmc_project.State.Chassis", "CurrentPowerState");
+
+    if (auto curPowerState = std::get_if<std::string>(&powerState))
+    {
+        if ("xyz.openbmc_project.State.Chassis.PowerState.On" == *curPowerState)
+        {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+        TODO: Add PEL.
+        Callout: Firmware callout
+        Type: Informational
+        Description: Chassis state can't be determined, defaulting to chassis
+        off. : e.what()
+    */
+    return false;
+}
+
+/**
+ * @brief API to check if host is in running state.
+ *
+ * This API reads the current host state from D-bus and returns true if the host
+ * is running.
+ *
+ * @return true if host is in running state. false otherwise.
+ */
+inline bool isHostRunning()
+{
+    const auto l_hostState = dbusUtility::readDbusProperty(
+        constants::hostService, constants::hostObjectPath,
+        constants::hostInterface, "CurrentHostState");
+
+    if (const auto l_currHostState = std::get_if<std::string>(&l_hostState))
+    {
+        if (*l_currHostState == constants::hostRunningState)
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/**
+ * @brief API to check if BMC is in ready state.
+ *
+ * This API reads the current state of BMC from D-bus and returns true if BMC is
+ * in ready state.
+ *
+ * @return true if BMC is ready, false otherwise.
+ */
+inline bool isBMCReady()
+{
+    const auto l_bmcState = dbusUtility::readDbusProperty(
+        constants::bmcStateService, constants::bmcZeroStateObject,
+        constants::bmcStateInterface, constants::currentBMCStateProperty);
+
+    if (const auto l_currBMCState = std::get_if<std::string>(&l_bmcState))
+    {
+        if (*l_currBMCState == constants::bmcReadyState)
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/**
+ * @brief An API to enable BMC reboot guard
+ *
+ * This API does a D-Bus method call to enable BMC reboot guard.
+ *
+ * @return On success, returns 0, otherwise returns -1.
+ */
+inline int EnableRebootGuard() noexcept
+{
+    int l_rc{constants::FAILURE};
+    try
+    {
+        auto l_bus = sdbusplus::bus::new_default();
+        auto l_method = l_bus.new_method_call(
+            constants::systemdService, constants::systemdObjectPath,
+            constants::systemdManagerInterface, "StartUnit");
+        l_method.append("reboot-guard-enable.service", "replace");
+        l_bus.call_noreply(l_method);
+        l_rc = constants::SUCCESS;
+    }
+    catch (const sdbusplus::exception::SdBusError& l_ex)
+    {
+        std::string l_errMsg =
+            "D-Bus call to enable BMC reboot guard failed for reason: ";
+        l_errMsg += l_ex.what();
+
+        logging::logMessage(l_errMsg);
+    }
+    return l_rc;
+}
+
+/**
+ * @brief An API to disable BMC reboot guard
+ *
+ * This API disables BMC reboot guard. This API has an inbuilt re-try mechanism.
+ * If Disable Reboot Guard fails, this API attempts to Disable Reboot Guard for
+ * 3 more times at an interval of 333ms.
+ *
+ * @return On success, returns 0, otherwise returns -1.
+ */
+inline int DisableRebootGuard() noexcept
+{
+    int l_rc{constants::FAILURE};
+
+    // A lambda which executes the DBus call to disable BMC reboot guard.
+    auto l_executeDisableRebootGuard = []() -> int {
+        int l_dBusCallRc{constants::FAILURE};
+        try
+        {
+            auto l_bus = sdbusplus::bus::new_default();
+            auto l_method = l_bus.new_method_call(
+                constants::systemdService, constants::systemdObjectPath,
+                constants::systemdManagerInterface, "StartUnit");
+            l_method.append("reboot-guard-disable.service", "replace");
+            l_bus.call_noreply(l_method);
+            l_dBusCallRc = constants::SUCCESS;
+        }
+        catch (const sdbusplus::exception::SdBusError& l_ex)
+        {}
+        return l_dBusCallRc;
+    };
+
+    if (constants::FAILURE == l_executeDisableRebootGuard())
+    {
+        std::function<void()> l_retryDisableRebootGuard;
+
+        // A lambda which tries to disable BMC reboot guard for 3 times at an
+        // interval of 333 ms.
+        l_retryDisableRebootGuard = [&]() {
+            constexpr int MAX_RETRIES{3};
+            static int l_numRetries{0};
+
+            if (l_numRetries < MAX_RETRIES)
+            {
+                l_numRetries++;
+                if (constants::FAILURE == l_executeDisableRebootGuard())
+                {
+                    // sleep for 333ms before next retry. This is just a random
+                    // value so that 3 re-tries * 333ms takes ~1 second in the
+                    // worst case.
+                    const std::chrono::milliseconds l_sleepTime{333};
+                    std::this_thread::sleep_for(l_sleepTime);
+                    l_retryDisableRebootGuard();
+                }
+                else
+                {
+                    l_numRetries = 0;
+                    l_rc = constants::SUCCESS;
+                }
+            }
+            else
+            {
+                // Failed to Disable Reboot Guard even after 3 retries.
+                logging::logMessage("Failed to Disable Reboot Guard after " +
+                                    std::to_string(MAX_RETRIES) + " re-tries");
+                l_numRetries = 0;
+            }
+        };
+
+        l_retryDisableRebootGuard();
+    }
+    else
+    {
+        l_rc = constants::SUCCESS;
+    }
+    return l_rc;
+}
+
+} // namespace dbusUtility
+} // namespace vpd
diff --git a/vpd-manager/include/utility/json_utility.hpp b/vpd-manager/include/utility/json_utility.hpp
new file mode 100644
index 0000000..3dab105
--- /dev/null
+++ b/vpd-manager/include/utility/json_utility.hpp
@@ -0,0 +1,1043 @@
+#pragma once
+
+#include "event_logger.hpp"
+#include "exceptions.hpp"
+#include "logger.hpp"
+#include "types.hpp"
+
+#include <gpiod.hpp>
+#include <nlohmann/json.hpp>
+#include <utility/common_utility.hpp>
+
+#include <fstream>
+#include <type_traits>
+#include <unordered_map>
+
+namespace vpd
+{
+namespace jsonUtility
+{
+
+// forward declaration of API for function map.
+bool processSystemCmdTag(const nlohmann::json& i_parsedConfigJson,
+                         const std::string& i_vpdFilePath,
+                         const std::string& i_baseAction,
+                         const std::string& i_flagToProcess);
+
+// forward declaration of API for function map.
+bool processGpioPresenceTag(
+    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
+    const std::string& i_baseAction, const std::string& i_flagToProcess);
+
+// forward declaration of API for function map.
+bool procesSetGpioTag(const nlohmann::json& i_parsedConfigJson,
+                      const std::string& i_vpdFilePath,
+                      const std::string& i_baseAction,
+                      const std::string& i_flagToProcess);
+
+// Function pointers to process tags from config JSON.
+typedef bool (*functionPtr)(
+    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
+    const std::string& i_baseAction, const std::string& i_flagToProcess);
+
+inline std::unordered_map<std::string, functionPtr> funcionMap{
+    {"gpioPresence", processGpioPresenceTag},
+    {"setGpio", procesSetGpioTag},
+    {"systemCmd", processSystemCmdTag}};
+
+/**
+ * @brief API to read VPD offset from JSON file.
+ *
+ * @param[in] i_sysCfgJsonObj - Parsed system config JSON object.
+ * @param[in] i_vpdFilePath - VPD file path.
+ * @return VPD offset if found in JSON, 0 otherwise.
+ */
+inline size_t getVPDOffset(const nlohmann::json& i_sysCfgJsonObj,
+                           const std::string& i_vpdFilePath)
+{
+    if (i_vpdFilePath.empty() || (i_sysCfgJsonObj.empty()) ||
+        (!i_sysCfgJsonObj.contains("frus")))
+    {
+        return 0;
+    }
+
+    if (i_sysCfgJsonObj["frus"].contains(i_vpdFilePath))
+    {
+        return i_sysCfgJsonObj["frus"][i_vpdFilePath].at(0).value("offset", 0);
+    }
+
+    const nlohmann::json& l_fruList =
+        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+    for (const auto& l_fru : l_fruList.items())
+    {
+        const auto l_fruPath = l_fru.key();
+
+        // check if given path is redundant FRU path
+        if (i_vpdFilePath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
+                                 "redundantEeprom", ""))
+        {
+            // Return the offset of redundant EEPROM taken from JSON.
+            return i_sysCfgJsonObj["frus"][l_fruPath].at(0).value("offset", 0);
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * @brief API to parse respective JSON.
+ *
+ * Exception is thrown in case of JSON parse error.
+ *
+ * @param[in] pathToJson - Path to JSON.
+ * @return Parsed JSON.
+ */
+inline nlohmann::json getParsedJson(const std::string& pathToJson)
+{
+    if (pathToJson.empty())
+    {
+        throw std::runtime_error("Path to JSON is missing");
+    }
+
+    if (!std::filesystem::exists(pathToJson) ||
+        std::filesystem::is_empty(pathToJson))
+    {
+        throw std::runtime_error("Incorrect File Path or empty file");
+    }
+
+    std::ifstream jsonFile(pathToJson);
+    if (!jsonFile)
+    {
+        throw std::runtime_error("Failed to access Json path = " + pathToJson);
+    }
+
+    try
+    {
+        return nlohmann::json::parse(jsonFile);
+    }
+    catch (const nlohmann::json::parse_error& e)
+    {
+        throw std::runtime_error("Failed to parse JSON file");
+    }
+}
+
+/**
+ * @brief Get inventory object path from system config JSON.
+ *
+ * Given either D-bus inventory path/FRU EEPROM path/redundant EEPROM path,
+ * this API returns D-bus inventory path if present in JSON.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object
+ * @param[in] i_vpdPath - Path to where VPD is stored.
+ *
+ * @throw std::runtime_error.
+ *
+ * @return On success a valid path is returned, on failure an empty string is
+ * returned or an exception is thrown.
+ */
+inline std::string getInventoryObjPathFromJson(
+    const nlohmann::json& i_sysCfgJsonObj, const std::string& i_vpdPath)
+{
+    if (i_vpdPath.empty())
+    {
+        throw std::runtime_error("Path parameter is empty.");
+    }
+
+    if (!i_sysCfgJsonObj.contains("frus"))
+    {
+        throw std::runtime_error("Missing frus tag in system config JSON.");
+    }
+
+    // check if given path is FRU path
+    if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
+    {
+        return i_sysCfgJsonObj["frus"][i_vpdPath].at(0).value(
+            "inventoryPath", "");
+    }
+
+    const nlohmann::json& l_fruList =
+        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+    for (const auto& l_fru : l_fruList.items())
+    {
+        const auto l_fruPath = l_fru.key();
+        const auto l_invObjPath =
+            i_sysCfgJsonObj["frus"][l_fruPath].at(0).value("inventoryPath", "");
+
+        // check if given path is redundant FRU path or inventory path
+        if (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
+                             "redundantEeprom", "") ||
+            (i_vpdPath == l_invObjPath))
+        {
+            return l_invObjPath;
+        }
+    }
+    return std::string();
+}
+
+/**
+ * @brief Process "PostFailAction" defined in config JSON.
+ *
+ * In case there is some error in the processing of "preAction" execution and a
+ * set of procedure needs to be done as a part of post fail action. This base
+ * action can be defined in the config JSON for that FRU and it will be handled
+ * under this API.
+ *
+ * @param[in] i_parsedConfigJson - config JSON
+ * @param[in] i_vpdFilePath - EEPROM file path
+ * @param[in] i_flagToProcess - To identify which flag(s) needs to be processed
+ * under PostFailAction tag of config JSON.
+ * @return - success or failure
+ */
+inline bool executePostFailAction(const nlohmann::json& i_parsedConfigJson,
+                                  const std::string& i_vpdFilePath,
+                                  const std::string& i_flagToProcess)
+{
+    if (i_parsedConfigJson.empty() || i_vpdFilePath.empty() ||
+        i_flagToProcess.empty())
+    {
+        logging::logMessage(
+            "Invalid parameters. Abort processing for post fail action");
+
+        return false;
+    }
+
+    if (!(i_parsedConfigJson["frus"][i_vpdFilePath].at(0))["PostFailAction"]
+             .contains(i_flagToProcess))
+    {
+        logging::logMessage(
+            "Config JSON missing flag " + i_flagToProcess +
+            " to execute post fail action for path = " + i_vpdFilePath);
+
+        return false;
+    }
+
+    for (const auto& l_tags : (i_parsedConfigJson["frus"][i_vpdFilePath].at(
+             0))["PostFailAction"][i_flagToProcess]
+                                  .items())
+    {
+        auto itrToFunction = funcionMap.find(l_tags.key());
+        if (itrToFunction != funcionMap.end())
+        {
+            if (!itrToFunction->second(i_parsedConfigJson, i_vpdFilePath,
+                                       "PostFailAction", i_flagToProcess))
+            {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+/**
+ * @brief Process "systemCmd" tag for a given FRU.
+ *
+ * The API will process "systemCmd" tag if it is defined in the config
+ * JSON for the given FRU.
+ *
+ * @param[in] i_parsedConfigJson - config JSON
+ * @param[in] i_vpdFilePath - EEPROM file path
+ * @param[in] i_baseAction - Base action for which this tag has been called.
+ * @param[in] i_flagToProcess - Flag nested under the base action for which this
+ * tag has been called.
+ * @return Execution status.
+ */
+inline bool processSystemCmdTag(
+    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
+    const std::string& i_baseAction, const std::string& i_flagToProcess)
+{
+    if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
+        i_baseAction.empty() || i_flagToProcess.empty())
+    {
+        logging::logMessage(
+            "Invalid parameter. Abort processing of processSystemCmd.");
+        return false;
+    }
+
+    if (!((i_parsedConfigJson["frus"][i_vpdFilePath].at(
+               0)[i_baseAction][i_flagToProcess]["systemCmd"])
+              .contains("cmd")))
+    {
+        logging::logMessage(
+            "Config JSON missing required information to execute system command for EEPROM " +
+            i_vpdFilePath);
+
+        return false;
+    }
+
+    try
+    {
+        const std::string& l_systemCommand =
+            i_parsedConfigJson["frus"][i_vpdFilePath].at(
+                0)[i_baseAction][i_flagToProcess]["systemCmd"]["cmd"];
+
+        commonUtility::executeCmd(l_systemCommand);
+        return true;
+    }
+    catch (const std::exception& e)
+    {
+        std::string l_errMsg = "Process system tag failed for exception: ";
+        l_errMsg += e.what();
+
+        logging::logMessage(l_errMsg);
+        return false;
+    }
+}
+
+/**
+ * @brief Checks for presence of a given FRU using GPIO line.
+ *
+ * This API returns the presence information of the FRU corresponding to the
+ * given VPD file path by setting the presence pin.
+ *
+ * @param[in] i_parsedConfigJson - config JSON
+ * @param[in] i_vpdFilePath - EEPROM file path
+ * @param[in] i_baseAction - Base action for which this tag has been called.
+ * @param[in] i_flagToProcess - Flag nested under the base action for which this
+ * tag has been called.
+ * @return Execution status.
+ */
+inline bool processGpioPresenceTag(
+    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
+    const std::string& i_baseAction, const std::string& i_flagToProcess)
+{
+    if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
+        i_baseAction.empty() || i_flagToProcess.empty())
+    {
+        logging::logMessage(
+            "Invalid parameter. Abort processing of processGpioPresence tag");
+        return false;
+    }
+
+    if (!(((i_parsedConfigJson["frus"][i_vpdFilePath].at(
+                0)[i_baseAction][i_flagToProcess]["gpioPresence"])
+               .contains("pin")) &&
+          ((i_parsedConfigJson["frus"][i_vpdFilePath].at(
+                0)[i_baseAction][i_flagToProcess]["gpioPresence"])
+               .contains("value"))))
+    {
+        logging::logMessage(
+            "Config JSON missing required information to detect presence for EEPROM " +
+            i_vpdFilePath);
+
+        return false;
+    }
+
+    // get the pin name
+    const std::string& l_presencePinName =
+        i_parsedConfigJson["frus"][i_vpdFilePath].at(
+            0)[i_baseAction][i_flagToProcess]["gpioPresence"]["pin"];
+
+    // get the pin value
+    uint8_t l_presencePinValue = i_parsedConfigJson["frus"][i_vpdFilePath].at(
+        0)[i_baseAction][i_flagToProcess]["gpioPresence"]["value"];
+
+    try
+    {
+        gpiod::line l_presenceLine = gpiod::find_line(l_presencePinName);
+
+        if (!l_presenceLine)
+        {
+            throw GpioException("Couldn't find the GPIO line.");
+        }
+
+        l_presenceLine.request({"Read the presence line",
+                                gpiod::line_request::DIRECTION_INPUT, 0});
+
+        return (l_presencePinValue == l_presenceLine.get_value());
+    }
+    catch (const std::exception& ex)
+    {
+        std::string l_errMsg = "Exception on GPIO line: ";
+        l_errMsg += l_presencePinName;
+        l_errMsg += " Reason: ";
+        l_errMsg += ex.what();
+        l_errMsg += " File: " + i_vpdFilePath + " Pel Logged";
+
+        // ToDo -- Update Internal Rc code.
+        EventLogger::createAsyncPelWithInventoryCallout(
+            types::ErrorType::GpioError, types::SeverityType::Informational,
+            {{getInventoryObjPathFromJson(i_parsedConfigJson, i_vpdFilePath),
+              types::CalloutPriority::High}},
+            std::source_location::current().file_name(),
+            std::source_location::current().function_name(), 0, l_errMsg,
+            std::nullopt, std::nullopt, std::nullopt, std::nullopt);
+
+        logging::logMessage(l_errMsg);
+
+        // Except when GPIO pin value is false, we go and try collecting the
+        // FRU VPD as we couldn't able to read GPIO pin value due to some
+        // error/exception. So returning true in error scenario.
+        return true;
+    }
+}
+
+/**
+ * @brief Process "setGpio" tag for a given FRU.
+ *
+ * This API enables the GPIO line.
+ *
+ * @param[in] i_parsedConfigJson - config JSON
+ * @param[in] i_vpdFilePath - EEPROM file path
+ * @param[in] i_baseAction - Base action for which this tag has been called.
+ * @param[in] i_flagToProcess - Flag nested under the base action for which this
+ * tag has been called.
+ * @return Execution status.
+ */
+inline bool procesSetGpioTag(
+    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
+    const std::string& i_baseAction, const std::string& i_flagToProcess)
+{
+    if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
+        i_baseAction.empty() || i_flagToProcess.empty())
+    {
+        logging::logMessage(
+            "Invalid parameter. Abort processing of procesSetGpio.");
+        return false;
+    }
+
+    if (!(((i_parsedConfigJson["frus"][i_vpdFilePath].at(
+                0)[i_baseAction][i_flagToProcess]["setGpio"])
+               .contains("pin")) &&
+          ((i_parsedConfigJson["frus"][i_vpdFilePath].at(
+                0)[i_baseAction][i_flagToProcess]["setGpio"])
+               .contains("value"))))
+    {
+        logging::logMessage(
+            "Config JSON missing required information to set gpio line for EEPROM " +
+            i_vpdFilePath);
+
+        return false;
+    }
+
+    const std::string& l_pinName = i_parsedConfigJson["frus"][i_vpdFilePath].at(
+        0)[i_baseAction][i_flagToProcess]["setGpio"]["pin"];
+
+    // Get the value to set
+    uint8_t l_pinValue = i_parsedConfigJson["frus"][i_vpdFilePath].at(
+        0)[i_baseAction][i_flagToProcess]["setGpio"]["value"];
+
+    logging::logMessage(
+        "Setting GPIO: " + l_pinName + " to " + std::to_string(l_pinValue));
+    try
+    {
+        gpiod::line l_outputLine = gpiod::find_line(l_pinName);
+
+        if (!l_outputLine)
+        {
+            throw GpioException("Couldn't find GPIO line.");
+        }
+
+        l_outputLine.request(
+            {"FRU Action", ::gpiod::line_request::DIRECTION_OUTPUT, 0},
+            l_pinValue);
+        return true;
+    }
+    catch (const std::exception& ex)
+    {
+        std::string l_errMsg = "Exception on GPIO line: ";
+        l_errMsg += l_pinName;
+        l_errMsg += " Reason: ";
+        l_errMsg += ex.what();
+        l_errMsg += " File: " + i_vpdFilePath + " Pel Logged";
+
+        // ToDo -- Update Internal RC code
+        EventLogger::createAsyncPelWithInventoryCallout(
+            types::ErrorType::GpioError, types::SeverityType::Informational,
+            {{getInventoryObjPathFromJson(i_parsedConfigJson, i_vpdFilePath),
+              types::CalloutPriority::High}},
+            std::source_location::current().file_name(),
+            std::source_location::current().function_name(), 0, l_errMsg,
+            std::nullopt, std::nullopt, std::nullopt, std::nullopt);
+
+        logging::logMessage(l_errMsg);
+
+        return false;
+    }
+}
+
+/**
+ * @brief Process any action, if defined in config JSON.
+ *
+ * If any FRU(s) requires any special handling, then this base action can be
+ * defined for that FRU in the config JSON, processing of which will be handled
+ * in this API.
+ * Examples of action - preAction, PostAction etc.
+ *
+ * @param[in] i_parsedConfigJson - config JSON
+ * @param[in] i_action - Base action to be performed.
+ * @param[in] i_vpdFilePath - EEPROM file path
+ * @param[in] i_flagToProcess - To identify which flag(s) needs to be processed
+ * under PreAction tag of config JSON.
+ * @return - success or failure
+ */
+inline bool executeBaseAction(
+    const nlohmann::json& i_parsedConfigJson, const std::string& i_action,
+    const std::string& i_vpdFilePath, const std::string& i_flagToProcess)
+{
+    if (i_flagToProcess.empty() || i_action.empty() || i_vpdFilePath.empty() ||
+        !i_parsedConfigJson.contains("frus"))
+    {
+        logging::logMessage("Invalid parameter");
+        return false;
+    }
+
+    if (!i_parsedConfigJson["frus"].contains(i_vpdFilePath))
+    {
+        logging::logMessage(
+            "File path: " + i_vpdFilePath + " not found in JSON");
+        return false;
+    }
+
+    if (!i_parsedConfigJson["frus"][i_vpdFilePath].at(0).contains(i_action))
+    {
+        logging::logMessage("Action [" + i_action +
+                            "] not defined for file path:" + i_vpdFilePath);
+        return false;
+    }
+
+    if (!(i_parsedConfigJson["frus"][i_vpdFilePath].at(0))[i_action].contains(
+            i_flagToProcess))
+    {
+        logging::logMessage("Config JSON missing flag [" + i_flagToProcess +
+                            "] to execute action for path = " + i_vpdFilePath);
+
+        return false;
+    }
+
+    const nlohmann::json& l_tagsJson =
+        (i_parsedConfigJson["frus"][i_vpdFilePath].at(
+            0))[i_action][i_flagToProcess];
+
+    for (const auto& l_tag : l_tagsJson.items())
+    {
+        auto itrToFunction = funcionMap.find(l_tag.key());
+        if (itrToFunction != funcionMap.end())
+        {
+            if (!itrToFunction->second(i_parsedConfigJson, i_vpdFilePath,
+                                       i_action, i_flagToProcess))
+            {
+                // In case any of the tag fails to execute. Mark action
+                // as failed for that flag.
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+/**
+ * @brief Get redundant FRU path from system config JSON
+ *
+ * Given either D-bus inventory path/FRU path/redundant FRU path, this
+ * API returns the redundant FRU path taken from "redundantEeprom" tag from
+ * system config JSON.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ * @param[in] i_vpdPath - Path to where VPD is stored.
+ *
+ * @throw std::runtime_error.
+ * @return On success return valid path, on failure return empty string.
+ */
+inline std::string getRedundantEepromPathFromJson(
+    const nlohmann::json& i_sysCfgJsonObj, const std::string& i_vpdPath)
+{
+    if (i_vpdPath.empty())
+    {
+        throw std::runtime_error("Path parameter is empty.");
+    }
+
+    if (!i_sysCfgJsonObj.contains("frus"))
+    {
+        throw std::runtime_error("Missing frus tag in system config JSON.");
+    }
+
+    // check if given path is FRU path
+    if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
+    {
+        return i_sysCfgJsonObj["frus"][i_vpdPath].at(0).value(
+            "redundantEeprom", "");
+    }
+
+    const nlohmann::json& l_fruList =
+        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+    for (const auto& l_fru : l_fruList.items())
+    {
+        const std::string& l_fruPath = l_fru.key();
+        const std::string& l_redundantFruPath =
+            i_sysCfgJsonObj["frus"][l_fruPath].at(0).value("redundantEeprom",
+                                                           "");
+
+        // check if given path is inventory path or redundant FRU path
+        if ((i_sysCfgJsonObj["frus"][l_fruPath].at(0).value("inventoryPath",
+                                                            "") == i_vpdPath) ||
+            (l_redundantFruPath == i_vpdPath))
+        {
+            return l_redundantFruPath;
+        }
+    }
+    return std::string();
+}
+
+/**
+ * @brief Get FRU EEPROM path from system config JSON
+ *
+ * Given either D-bus inventory path/FRU EEPROM path/redundant EEPROM path,
+ * this API returns FRU EEPROM path if present in JSON.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object
+ * @param[in] i_vpdPath - Path to where VPD is stored.
+ *
+ * @throw std::runtime_error.
+ *
+ * @return On success return valid path, on failure return empty string.
+ */
+inline std::string getFruPathFromJson(const nlohmann::json& i_sysCfgJsonObj,
+                                      const std::string& i_vpdPath)
+{
+    if (i_vpdPath.empty())
+    {
+        throw std::runtime_error("Path parameter is empty.");
+    }
+
+    if (!i_sysCfgJsonObj.contains("frus"))
+    {
+        throw std::runtime_error("Missing frus tag in system config JSON.");
+    }
+
+    // check if given path is FRU path
+    if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
+    {
+        return i_vpdPath;
+    }
+
+    const nlohmann::json& l_fruList =
+        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+    for (const auto& l_fru : l_fruList.items())
+    {
+        const auto l_fruPath = l_fru.key();
+
+        // check if given path is redundant FRU path or inventory path
+        if (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
+                             "redundantEeprom", "") ||
+            (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
+                              "inventoryPath", "")))
+        {
+            return l_fruPath;
+        }
+    }
+    return std::string();
+}
+
+/**
+ * @brief An API to check backup and restore VPD is required.
+ *
+ * The API checks if there is provision for backup and restore mentioned in the
+ * system config JSON, by looking "backupRestoreConfigPath" tag.
+ * Checks if the path mentioned is a hardware path, by checking if the file path
+ * exists and size of contents in the path.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ *
+ * @return true if backup and restore is required, false otherwise.
+ */
+inline bool isBackupAndRestoreRequired(const nlohmann::json& i_sysCfgJsonObj)
+{
+    try
+    {
+        const std::string& l_backupAndRestoreCfgFilePath =
+            i_sysCfgJsonObj.value("backupRestoreConfigPath", "");
+        if (!l_backupAndRestoreCfgFilePath.empty() &&
+            std::filesystem::exists(l_backupAndRestoreCfgFilePath) &&
+            !std::filesystem::is_empty(l_backupAndRestoreCfgFilePath))
+        {
+            return true;
+        }
+    }
+    catch (std::exception& ex)
+    {
+        logging::logMessage(ex.what());
+    }
+    return false;
+}
+
+/** @brief API to check if an action is required for given EEPROM path.
+ *
+ * System config JSON can contain pre-action, post-action etc. like actions
+ * defined for an EEPROM path. The API will check if any such action is defined
+ * for the EEPROM.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ * @param[in] i_vpdFruPath - EEPROM path.
+ * @param[in] i_action - Action to be checked.
+ * @param[in] i_flowFlag - Denotes the flow w.r.t which the action should be
+ * triggered.
+ * @return - True if action is defined for the flow, false otherwise.
+ */
+inline bool isActionRequired(
+    const nlohmann::json& i_sysCfgJsonObj, const std::string& i_vpdFruPath,
+    const std::string& i_action, const std::string& i_flowFlag)
+{
+    if (i_vpdFruPath.empty() || i_action.empty() || i_flowFlag.empty())
+    {
+        logging::logMessage("Invalid parameters recieved.");
+        return false;
+    }
+
+    if (!i_sysCfgJsonObj.contains("frus"))
+    {
+        logging::logMessage("Invalid JSON object recieved.");
+        return false;
+    }
+
+    if (!i_sysCfgJsonObj["frus"].contains(i_vpdFruPath))
+    {
+        logging::logMessage(
+            "JSON object does not contain EEPROM path " + i_vpdFruPath);
+        return false;
+    }
+
+    if ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0)).contains(i_action))
+    {
+        if ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0))[i_action].contains(
+                i_flowFlag))
+        {
+            return true;
+        }
+
+        logging::logMessage("Flow flag: [" + i_flowFlag +
+                            "], not found in JSON for path: " + i_vpdFruPath);
+        return false;
+    }
+    return false;
+}
+
+/**
+ * @brief An API to return list of FRUs that needs GPIO polling.
+ *
+ * An API that checks for the FRUs that requires GPIO polling and returns
+ * a list of FRUs that needs polling. Returns an empty list if there are
+ * no FRUs that requires polling.
+ *
+ * @throw std::runtime_error
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ *
+ * @return list of FRUs parameters that needs polling.
+ */
+inline std::vector<std::string>
+    getListOfGpioPollingFrus(const nlohmann::json& i_sysCfgJsonObj)
+{
+    if (i_sysCfgJsonObj.empty())
+    {
+        throw std::runtime_error("Invalid Parameters");
+    }
+
+    if (!i_sysCfgJsonObj.contains("frus"))
+    {
+        throw std::runtime_error("Missing frus section in system config JSON");
+    }
+
+    std::vector<std::string> l_gpioPollingRequiredFrusList;
+
+    for (const auto& l_fru : i_sysCfgJsonObj["frus"].items())
+    {
+        const auto l_fruPath = l_fru.key();
+
+        try
+        {
+            if (isActionRequired(i_sysCfgJsonObj, l_fruPath, "pollingRequired",
+                                 "hotPlugging"))
+            {
+                if (i_sysCfgJsonObj["frus"][l_fruPath]
+                        .at(0)["pollingRequired"]["hotPlugging"]
+                        .contains("gpioPresence"))
+                {
+                    l_gpioPollingRequiredFrusList.push_back(l_fruPath);
+                }
+            }
+        }
+        catch (const std::exception& l_ex)
+        {
+            logging::logMessage(l_ex.what());
+        }
+    }
+
+    return l_gpioPollingRequiredFrusList;
+}
+
+/**
+ * @brief Get all related path(s) to update keyword value.
+ *
+ * Given FRU EEPROM path/Inventory path needs keyword's value update, this API
+ * returns tuple of FRU EEPROM path, inventory path and redundant EEPROM path if
+ * exists in the system config JSON.
+ *
+ * Note: If the inventory object path or redundant EEPROM path(s) are not found
+ * in the system config JSON, corresponding fields will have empty value in the
+ * returning tuple.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ * @param[in,out] io_vpdPath - Inventory object path or FRU EEPROM path.
+ *
+ * @return On success returns tuple of EEPROM path, inventory path & redundant
+ * path, on failure returns tuple with given input path alone.
+ */
+inline std::tuple<std::string, std::string, std::string>
+    getAllPathsToUpdateKeyword(const nlohmann::json& i_sysCfgJsonObj,
+                               std::string io_vpdPath)
+{
+    types::Path l_inventoryObjPath;
+    types::Path l_redundantFruPath;
+    try
+    {
+        if (!i_sysCfgJsonObj.empty())
+        {
+            // Get hardware path from system config JSON.
+            const types::Path l_fruPath =
+                jsonUtility::getFruPathFromJson(i_sysCfgJsonObj, io_vpdPath);
+
+            if (!l_fruPath.empty())
+            {
+                io_vpdPath = l_fruPath;
+
+                // Get inventory object path from system config JSON
+                l_inventoryObjPath = jsonUtility::getInventoryObjPathFromJson(
+                    i_sysCfgJsonObj, l_fruPath);
+
+                // Get redundant hardware path if present in system config JSON
+                l_redundantFruPath =
+                    jsonUtility::getRedundantEepromPathFromJson(i_sysCfgJsonObj,
+                                                                l_fruPath);
+            }
+        }
+    }
+    catch (const std::exception& l_exception)
+    {
+        logging::logMessage(
+            "Failed to get all paths to update keyword value, error " +
+            std::string(l_exception.what()));
+    }
+    return std::make_tuple(io_vpdPath, l_inventoryObjPath, l_redundantFruPath);
+}
+
+/**
+ * @brief An API to get DBus service name.
+ *
+ * Given DBus inventory path, this API returns DBus service name if present in
+ * the JSON.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ * @param[in] l_inventoryPath - DBus inventory path.
+ *
+ * @return On success returns the service name present in the system config
+ * JSON, otherwise empty string.
+ *
+ * Note: Caller has to handle in case of empty string received.
+ */
+inline std::string getServiceName(const nlohmann::json& i_sysCfgJsonObj,
+                                  const std::string& l_inventoryPath)
+{
+    try
+    {
+        if (l_inventoryPath.empty())
+        {
+            throw std::runtime_error("Path parameter is empty.");
+        }
+
+        if (!i_sysCfgJsonObj.contains("frus"))
+        {
+            throw std::runtime_error("Missing frus tag in system config JSON.");
+        }
+
+        const nlohmann::json& l_listOfFrus =
+            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+        for (const auto& l_frus : l_listOfFrus.items())
+        {
+            for (const auto& l_inventoryItem : l_frus.value())
+            {
+                if (l_inventoryPath.compare(l_inventoryItem["inventoryPath"]) ==
+                    constants::STR_CMP_SUCCESS)
+                {
+                    return l_inventoryItem["serviceName"];
+                }
+            }
+        }
+        throw std::runtime_error(
+            "Inventory path not found in the system config JSON");
+    }
+    catch (const std::exception& l_exception)
+    {
+        logging::logMessage(
+            "Error while getting DBus service name for given path " +
+            l_inventoryPath + ", error: " + std::string(l_exception.what()));
+        // TODO:log PEL
+    }
+    return std::string{};
+}
+
+/**
+ * @brief An API to check if a FRU is tagged as "powerOffOnly"
+ *
+ * Given the system config JSON and VPD FRU path, this API checks if the FRU
+ * VPD can be collected at Chassis Power Off state only.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ * @param[in] i_vpdFruPath - EEPROM path.
+ * @return - True if FRU VPD can be collected at Chassis Power Off state only.
+ *           False otherwise
+ */
+inline bool isFruPowerOffOnly(const nlohmann::json& i_sysCfgJsonObj,
+                              const std::string& i_vpdFruPath)
+{
+    if (i_vpdFruPath.empty())
+    {
+        logging::logMessage("FRU path is empty.");
+        return false;
+    }
+
+    if (!i_sysCfgJsonObj.contains("frus"))
+    {
+        logging::logMessage("Missing frus tag in system config JSON.");
+        return false;
+    }
+
+    if (!i_sysCfgJsonObj["frus"].contains(i_vpdFruPath))
+    {
+        logging::logMessage("JSON object does not contain EEPROM path \'" +
+                            i_vpdFruPath + "\'");
+        return false;
+    }
+
+    return ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0))
+                .contains("powerOffOnly") &&
+            (i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0)["powerOffOnly"]));
+}
+
+/**
+ * @brief API which tells if the FRU is replaceable at runtime
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ * @param[in] i_vpdFruPath - EEPROM path.
+ *
+ * @return true if FRU is replaceable at runtime. false otherwise.
+ */
+inline bool isFruReplaceableAtRuntime(const nlohmann::json& i_sysCfgJsonObj,
+                                      const std::string& i_vpdFruPath)
+{
+    try
+    {
+        if (i_vpdFruPath.empty())
+        {
+            throw std::runtime_error("Given FRU path is empty.");
+        }
+
+        if (i_sysCfgJsonObj.empty() || (!i_sysCfgJsonObj.contains("frus")))
+        {
+            throw std::runtime_error("Invalid system config JSON object.");
+        }
+
+        return ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0))
+                    .contains("replaceableAtRuntime") &&
+                (i_sysCfgJsonObj["frus"][i_vpdFruPath].at(
+                    0)["replaceableAtRuntime"]));
+    }
+    catch (const std::exception& l_error)
+    {
+        // TODO: Log PEL
+        logging::logMessage(l_error.what());
+    }
+
+    return false;
+}
+
+/**
+ * @brief API which tells if the FRU is replaceable at standby
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ * @param[in] i_vpdFruPath - EEPROM path.
+ *
+ * @return true if FRU is replaceable at standby. false otherwise.
+ */
+inline bool isFruReplaceableAtStandby(const nlohmann::json& i_sysCfgJsonObj,
+                                      const std::string& i_vpdFruPath)
+{
+    try
+    {
+        if (i_vpdFruPath.empty())
+        {
+            throw std::runtime_error("Given FRU path is empty.");
+        }
+
+        if (i_sysCfgJsonObj.empty() || (!i_sysCfgJsonObj.contains("frus")))
+        {
+            throw std::runtime_error("Invalid system config JSON object.");
+        }
+
+        return ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0))
+                    .contains("replaceableAtStandby") &&
+                (i_sysCfgJsonObj["frus"][i_vpdFruPath].at(
+                    0)["replaceableAtStandby"]));
+    }
+    catch (const std::exception& l_error)
+    {
+        // TODO: Log PEL
+        logging::logMessage(l_error.what());
+    }
+
+    return false;
+}
+
+/**
+ * @brief API to get list of FRUs replaceable at standby from JSON.
+ *
+ * The API will return a vector of FRUs inventory path which are replaceable at
+ * standby.
+ * The API can throw exception in case of error scenarios. Caller's
+ * responsibility to handle those exceptions.
+ *
+ * @param[in] i_sysCfgJsonObj - System config JSON object.
+ *
+ * @return - List of FRUs replaceable at standby.
+ */
+inline std::vector<std::string>
+    getListOfFrusReplaceableAtStandby(const nlohmann::json& i_sysCfgJsonObj)
+{
+    std::vector<std::string> l_frusReplaceableAtStandby;
+
+    if (!i_sysCfgJsonObj.contains("frus"))
+    {
+        logging::logMessage("Missing frus tag in system config JSON.");
+        return l_frusReplaceableAtStandby;
+    }
+
+    const nlohmann::json& l_fruList =
+        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+    for (const auto& l_fru : l_fruList.items())
+    {
+        if (i_sysCfgJsonObj["frus"][l_fru.key()].at(0).value(
+                "replaceableAtStandby", false))
+        {
+            const std::string& l_inventoryObjectPath =
+                i_sysCfgJsonObj["frus"][l_fru.key()].at(0).value(
+                    "inventoryPath", "");
+
+            if (!l_inventoryObjectPath.empty())
+            {
+                l_frusReplaceableAtStandby.emplace_back(l_inventoryObjectPath);
+            }
+        }
+    }
+
+    return l_frusReplaceableAtStandby;
+}
+
+} // namespace jsonUtility
+} // namespace vpd
diff --git a/vpd-manager/include/utility/vpd_specific_utility.hpp b/vpd-manager/include/utility/vpd_specific_utility.hpp
new file mode 100644
index 0000000..d6b92fd
--- /dev/null
+++ b/vpd-manager/include/utility/vpd_specific_utility.hpp
@@ -0,0 +1,556 @@
+#pragma once
+
+#include "config.h"
+
+#include "constants.hpp"
+#include "exceptions.hpp"
+#include "logger.hpp"
+#include "types.hpp"
+
+#include <nlohmann/json.hpp>
+#include <utility/common_utility.hpp>
+#include <utility/dbus_utility.hpp>
+
+#include <filesystem>
+#include <fstream>
+#include <regex>
+
+namespace vpd
+{
+namespace vpdSpecificUtility
+{
+/**
+ * @brief API to generate file name for bad VPD.
+ *
+ * For i2c eeproms - the pattern of the vpd-name will be
+ * i2c-<bus-number>-<eeprom-address>.
+ * For spi eeproms - the pattern of the vpd-name will be spi-<spi-number>.
+ *
+ * @param[in] vpdFilePath - file path of the vpd.
+ * @return Generated file name.
+ */
+inline std::string generateBadVPDFileName(const std::string& vpdFilePath)
+{
+    std::string badVpdFileName = BAD_VPD_DIR;
+    if (vpdFilePath.find("i2c") != std::string::npos)
+    {
+        badVpdFileName += "i2c-";
+        std::regex i2cPattern("(at24/)([0-9]+-[0-9]+)\\/");
+        std::smatch match;
+        if (std::regex_search(vpdFilePath, match, i2cPattern))
+        {
+            badVpdFileName += match.str(2);
+        }
+    }
+    else if (vpdFilePath.find("spi") != std::string::npos)
+    {
+        std::regex spiPattern("((spi)[0-9]+)(.0)");
+        std::smatch match;
+        if (std::regex_search(vpdFilePath, match, spiPattern))
+        {
+            badVpdFileName += match.str(1);
+        }
+    }
+    return badVpdFileName;
+}
+
+/**
+ * @brief API which dumps the broken/bad vpd in a directory.
+ * When the vpd is bad, this API places  the bad vpd file inside
+ * "/tmp/bad-vpd" in BMC, in order to collect bad VPD data as a part of user
+ * initiated BMC dump.
+ *
+ * Note: Throws exception in case of any failure.
+ *
+ * @param[in] vpdFilePath - vpd file path
+ * @param[in] vpdVector - vpd vector
+ */
+inline void dumpBadVpd(const std::string& vpdFilePath,
+                       const types::BinaryVector& vpdVector)
+{
+    std::filesystem::create_directory(BAD_VPD_DIR);
+    auto badVpdPath = generateBadVPDFileName(vpdFilePath);
+
+    if (std::filesystem::exists(badVpdPath))
+    {
+        std::error_code ec;
+        std::filesystem::remove(badVpdPath, ec);
+        if (ec) // error code
+        {
+            std::string error = "Error removing the existing broken vpd in ";
+            error += badVpdPath;
+            error += ". Error code : ";
+            error += ec.value();
+            error += ". Error message : ";
+            error += ec.message();
+            throw std::runtime_error(error);
+        }
+    }
+
+    std::ofstream badVpdFileStream(badVpdPath, std::ofstream::binary);
+    if (badVpdFileStream.is_open())
+    {
+        throw std::runtime_error(
+            "Failed to open bad vpd file path in /tmp/bad-vpd. "
+            "Unable to dump the broken/bad vpd file.");
+    }
+
+    badVpdFileStream.write(reinterpret_cast<const char*>(vpdVector.data()),
+                           vpdVector.size());
+}
+
+/**
+ * @brief An API to read value of a keyword.
+ *
+ * Note: Throws exception. Caller needs to handle.
+ *
+ * @param[in] kwdValueMap - A map having Kwd value pair.
+ * @param[in] kwd - keyword name.
+ * @param[out] kwdValue - Value of the keyword read from map.
+ */
+inline void getKwVal(const types::IPZKwdValueMap& kwdValueMap,
+                     const std::string& kwd, std::string& kwdValue)
+{
+    if (kwd.empty())
+    {
+        logging::logMessage("Invalid parameters");
+        throw std::runtime_error("Invalid parameters");
+    }
+
+    auto itrToKwd = kwdValueMap.find(kwd);
+    if (itrToKwd != kwdValueMap.end())
+    {
+        kwdValue = itrToKwd->second;
+        return;
+    }
+
+    throw std::runtime_error("Keyword not found");
+}
+
+/**
+ * @brief An API to process encoding of a keyword.
+ *
+ * @param[in] keyword - Keyword to be processed.
+ * @param[in] encoding - Type of encoding.
+ * @return Value after being processed for encoded type.
+ */
+inline std::string encodeKeyword(const std::string& keyword,
+                                 const std::string& encoding)
+{
+    // Default value is keyword value
+    std::string result(keyword.begin(), keyword.end());
+
+    if (encoding == "MAC")
+    {
+        result.clear();
+        size_t firstByte = keyword[0];
+        result += commonUtility::toHex(firstByte >> 4);
+        result += commonUtility::toHex(firstByte & 0x0f);
+        for (size_t i = 1; i < keyword.size(); ++i)
+        {
+            result += ":";
+            result += commonUtility::toHex(keyword[i] >> 4);
+            result += commonUtility::toHex(keyword[i] & 0x0f);
+        }
+    }
+    else if (encoding == "DATE")
+    {
+        // Date, represent as
+        // <year>-<month>-<day> <hour>:<min>
+        result.clear();
+        static constexpr uint8_t skipPrefix = 3;
+
+        auto strItr = keyword.begin();
+        advance(strItr, skipPrefix);
+        for_each(strItr, keyword.end(), [&result](size_t c) { result += c; });
+
+        result.insert(constants::BD_YEAR_END, 1, '-');
+        result.insert(constants::BD_MONTH_END, 1, '-');
+        result.insert(constants::BD_DAY_END, 1, ' ');
+        result.insert(constants::BD_HOUR_END, 1, ':');
+    }
+
+    return result;
+}
+
+/**
+ * @brief Helper function to insert or merge in map.
+ *
+ * This method checks in an interface if the given interface exists. If the
+ * interface key already exists, property map is inserted corresponding to it.
+ * If the key does'nt exist then given interface and property map pair is newly
+ * created. If the property present in propertymap already exist in the
+ * InterfaceMap, then the new property value is ignored.
+ *
+ * @param[in,out] map - Interface map.
+ * @param[in] interface - Interface to be processed.
+ * @param[in] propertyMap - new property map that needs to be emplaced.
+ */
+inline void insertOrMerge(types::InterfaceMap& map,
+                          const std::string& interface,
+                          types::PropertyMap&& propertyMap)
+{
+    if (map.find(interface) != map.end())
+    {
+        try
+        {
+            auto& prop = map.at(interface);
+            std::for_each(propertyMap.begin(), propertyMap.end(),
+                          [&prop](auto l_keyValue) {
+                              prop[l_keyValue.first] = l_keyValue.second;
+                          });
+        }
+        catch (const std::exception& l_ex)
+        {
+            // ToDo:: Log PEL
+            logging::logMessage(
+                "Inserting properties into interface[" + interface +
+                "] map is failed, reason: " + std::string(l_ex.what()));
+        }
+    }
+    else
+    {
+        map.emplace(interface, propertyMap);
+    }
+}
+
+/**
+ * @brief API to expand unpanded location code.
+ *
+ * Note: The API handles all the exception internally, in case of any error
+ * unexpanded location code will be returned as it is.
+ *
+ * @param[in] unexpandedLocationCode - Unexpanded location code.
+ * @param[in] parsedVpdMap - Parsed VPD map.
+ * @return Expanded location code. In case of any error, unexpanded is returned
+ * as it is.
+ */
+inline std::string
+    getExpandedLocationCode(const std::string& unexpandedLocationCode,
+                            const types::VPDMapVariant& parsedVpdMap)
+{
+    auto expanded{unexpandedLocationCode};
+
+    try
+    {
+        // Expanded location code is formed by combining two keywords
+        // depending on type in unexpanded one. Second one is always "SE".
+        std::string kwd1, kwd2{constants::kwdSE};
+
+        // interface to search for required keywords;
+        std::string kwdInterface;
+
+        // record which holds the required keywords.
+        std::string recordName;
+
+        auto pos = unexpandedLocationCode.find("fcs");
+        if (pos != std::string::npos)
+        {
+            kwd1 = constants::kwdFC;
+            kwdInterface = constants::vcenInf;
+            recordName = constants::recVCEN;
+        }
+        else
+        {
+            pos = unexpandedLocationCode.find("mts");
+            if (pos != std::string::npos)
+            {
+                kwd1 = constants::kwdTM;
+                kwdInterface = constants::vsysInf;
+                recordName = constants::recVSYS;
+            }
+            else
+            {
+                throw std::runtime_error(
+                    "Error detecting type of unexpanded location code.");
+            }
+        }
+
+        std::string firstKwdValue, secondKwdValue;
+
+        if (auto ipzVpdMap = std::get_if<types::IPZVpdMap>(&parsedVpdMap);
+            ipzVpdMap && (*ipzVpdMap).find(recordName) != (*ipzVpdMap).end())
+        {
+            auto itrToVCEN = (*ipzVpdMap).find(recordName);
+            // The exceptions will be cautght at end.
+            getKwVal(itrToVCEN->second, kwd1, firstKwdValue);
+            getKwVal(itrToVCEN->second, kwd2, secondKwdValue);
+        }
+        else
+        {
+            std::array<const char*, 1> interfaceList = {kwdInterface.c_str()};
+
+            types::MapperGetObject mapperRetValue = dbusUtility::getObjectMap(
+                std::string(constants::systemVpdInvPath), interfaceList);
+
+            if (mapperRetValue.empty())
+            {
+                throw std::runtime_error("Mapper failed to get service");
+            }
+
+            const std::string& serviceName = std::get<0>(mapperRetValue.at(0));
+
+            auto retVal = dbusUtility::readDbusProperty(
+                serviceName, std::string(constants::systemVpdInvPath),
+                kwdInterface, kwd1);
+
+            if (auto kwdVal = std::get_if<types::BinaryVector>(&retVal))
+            {
+                firstKwdValue.assign(
+                    reinterpret_cast<const char*>(kwdVal->data()),
+                    kwdVal->size());
+            }
+            else
+            {
+                throw std::runtime_error(
+                    "Failed to read value of " + kwd1 + " from Bus");
+            }
+
+            retVal = dbusUtility::readDbusProperty(
+                serviceName, std::string(constants::systemVpdInvPath),
+                kwdInterface, kwd2);
+
+            if (auto kwdVal = std::get_if<types::BinaryVector>(&retVal))
+            {
+                secondKwdValue.assign(
+                    reinterpret_cast<const char*>(kwdVal->data()),
+                    kwdVal->size());
+            }
+            else
+            {
+                throw std::runtime_error(
+                    "Failed to read value of " + kwd2 + " from Bus");
+            }
+        }
+
+        if (unexpandedLocationCode.find("fcs") != std::string::npos)
+        {
+            // TODO: See if ND0 can be placed in the JSON
+            expanded.replace(
+                pos, 3, firstKwdValue.substr(0, 4) + ".ND0." + secondKwdValue);
+        }
+        else
+        {
+            replace(firstKwdValue.begin(), firstKwdValue.end(), '-', '.');
+            expanded.replace(pos, 3, firstKwdValue + "." + secondKwdValue);
+        }
+    }
+    catch (const std::exception& ex)
+    {
+        logging::logMessage("Failed to expand location code with exception: " +
+                            std::string(ex.what()));
+    }
+
+    return expanded;
+}
+
+/**
+ * @brief An API to get VPD in a vector.
+ *
+ * The vector is required by the respective parser to fill the VPD map.
+ * Note: API throws exception in case of failure. Caller needs to handle.
+ *
+ * @param[in] vpdFilePath - EEPROM path of the FRU.
+ * @param[out] vpdVector - VPD in vector form.
+ * @param[in] vpdStartOffset - Offset of VPD data in EEPROM.
+ */
+inline void getVpdDataInVector(const std::string& vpdFilePath,
+                               types::BinaryVector& vpdVector,
+                               size_t& vpdStartOffset)
+{
+    try
+    {
+        std::fstream vpdFileStream;
+        vpdFileStream.exceptions(
+            std::ifstream::badbit | std::ifstream::failbit);
+        vpdFileStream.open(vpdFilePath, std::ios::in | std::ios::binary);
+        auto vpdSizeToRead = std::min(std::filesystem::file_size(vpdFilePath),
+                                      static_cast<uintmax_t>(65504));
+        vpdVector.resize(vpdSizeToRead);
+
+        vpdFileStream.seekg(vpdStartOffset, std::ios_base::beg);
+        vpdFileStream.read(reinterpret_cast<char*>(&vpdVector[0]),
+                           vpdSizeToRead);
+
+        vpdVector.resize(vpdFileStream.gcount());
+        vpdFileStream.clear(std::ios_base::eofbit);
+    }
+    catch (const std::ifstream::failure& fail)
+    {
+        std::cerr << "Exception in file handling [" << vpdFilePath
+                  << "] error : " << fail.what();
+        throw;
+    }
+}
+
+/**
+ * @brief An API to get D-bus representation of given VPD keyword.
+ *
+ * @param[in] i_keywordName - VPD keyword name.
+ *
+ * @return D-bus representation of given keyword.
+ */
+inline std::string getDbusPropNameForGivenKw(const std::string& i_keywordName)
+{
+    // Check for "#" prefixed VPD keyword.
+    if ((i_keywordName.size() == vpd::constants::TWO_BYTES) &&
+        (i_keywordName.at(0) == constants::POUND_KW))
+    {
+        // D-bus doesn't support "#". Replace "#" with "PD_" for those "#"
+        // prefixed keywords.
+        return (std::string(constants::POUND_KW_PREFIX) +
+                i_keywordName.substr(1));
+    }
+
+    // Return the keyword name back, if D-bus representation is same as the VPD
+    // keyword name.
+    return i_keywordName;
+}
+
+/**
+ * @brief API to find CCIN in parsed VPD map.
+ *
+ * Few FRUs need some special handling. To identify those FRUs CCIN are used.
+ * The API will check from parsed VPD map if the FRU is the one with desired
+ * CCIN.
+ *
+ * @throw std::runtime_error
+ * @throw DataException
+ *
+ * @param[in] i_JsonObject - Any JSON which contains CCIN tag to match.
+ * @param[in] i_parsedVpdMap - Parsed VPD map.
+ * @return True if found, false otherwise.
+ */
+inline bool findCcinInVpd(const nlohmann::json& i_JsonObject,
+                          const types::VPDMapVariant& i_parsedVpdMap)
+{
+    if (i_JsonObject.empty())
+    {
+        throw std::runtime_error("Json object is empty. Can't find CCIN");
+    }
+
+    if (auto l_ipzVPDMap = std::get_if<types::IPZVpdMap>(&i_parsedVpdMap))
+    {
+        auto l_itrToRec = (*l_ipzVPDMap).find("VINI");
+        if (l_itrToRec == (*l_ipzVPDMap).end())
+        {
+            throw DataException(
+                "VINI record not found in parsed VPD. Can't find CCIN");
+        }
+
+        std::string l_ccinFromVpd;
+        vpdSpecificUtility::getKwVal(l_itrToRec->second, "CC", l_ccinFromVpd);
+        if (l_ccinFromVpd.empty())
+        {
+            throw DataException("Empty CCIN value in VPD map. Can't find CCIN");
+        }
+
+        transform(l_ccinFromVpd.begin(), l_ccinFromVpd.end(),
+                  l_ccinFromVpd.begin(), ::toupper);
+
+        for (std::string l_ccinValue : i_JsonObject["ccin"])
+        {
+            transform(l_ccinValue.begin(), l_ccinValue.end(),
+                      l_ccinValue.begin(), ::toupper);
+
+            if (l_ccinValue.compare(l_ccinFromVpd) ==
+                constants::STR_CMP_SUCCESS)
+            {
+                // CCIN found
+                return true;
+            }
+        }
+
+        logging::logMessage("No match found for CCIN");
+        return false;
+    }
+
+    logging::logMessage("VPD type not supported. Can't find CCIN");
+    return false;
+}
+
+/**
+ * @brief API to reset data of a FRU populated under PIM.
+ *
+ * This API resets the data for particular interfaces of a FRU under PIM.
+ *
+ * @param[in] i_objectPath - DBus object path of the FRU.
+ * @param[in] io_interfaceMap - Interface and its properties map.
+ */
+inline void resetDataUnderPIM(const std::string& i_objectPath,
+                              types::InterfaceMap& io_interfaceMap)
+{
+    try
+    {
+        std::array<const char*, 0> l_interfaces;
+        const types::MapperGetObject& l_getObjectMap =
+            dbusUtility::getObjectMap(i_objectPath, l_interfaces);
+
+        const std::vector<std::string>& l_vpdRelatedInterfaces{
+            constants::operationalStatusInf, constants::inventoryItemInf,
+            constants::assetInf};
+
+        for (const auto& [l_service, l_interfaceList] : l_getObjectMap)
+        {
+            if (l_service.compare(constants::pimServiceName) !=
+                constants::STR_CMP_SUCCESS)
+            {
+                continue;
+            }
+
+            for (const auto& l_interface : l_interfaceList)
+            {
+                if ((l_interface.find(constants::ipzVpdInf) !=
+                     std::string::npos) ||
+                    ((std::find(l_vpdRelatedInterfaces.begin(),
+                                l_vpdRelatedInterfaces.end(), l_interface)) !=
+                     l_vpdRelatedInterfaces.end()))
+                {
+                    const types::PropertyMap& l_propertyValueMap =
+                        dbusUtility::getPropertyMap(l_service, i_objectPath,
+                                                    l_interface);
+
+                    types::PropertyMap l_propertyMap;
+
+                    for (const auto& l_aProperty : l_propertyValueMap)
+                    {
+                        const std::string& l_propertyName = l_aProperty.first;
+                        const auto& l_propertyValue = l_aProperty.second;
+
+                        if (std::holds_alternative<types::BinaryVector>(
+                                l_propertyValue))
+                        {
+                            l_propertyMap.emplace(l_propertyName,
+                                                  types::BinaryVector{});
+                        }
+                        else if (std::holds_alternative<std::string>(
+                                     l_propertyValue))
+                        {
+                            l_propertyMap.emplace(l_propertyName,
+                                                  std::string{});
+                        }
+                        else if (std::holds_alternative<bool>(l_propertyValue))
+                        {
+                            // ToDo -- Update the functional status property
+                            // to true.
+                            if (l_propertyName.compare("Present") ==
+                                constants::STR_CMP_SUCCESS)
+                            {
+                                l_propertyMap.emplace(l_propertyName, false);
+                            }
+                        }
+                    }
+                    io_interfaceMap.emplace(l_interface,
+                                            std::move(l_propertyMap));
+                }
+            }
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage("Failed to remove VPD for FRU: " + i_objectPath +
+                            " with error: " + std::string(l_ex.what()));
+    }
+}
+} // namespace vpdSpecificUtility
+} // namespace vpd
diff --git a/vpd-manager/include/worker.hpp b/vpd-manager/include/worker.hpp
new file mode 100644
index 0000000..85a1818
--- /dev/null
+++ b/vpd-manager/include/worker.hpp
@@ -0,0 +1,529 @@
+#pragma once
+
+#include "constants.hpp"
+#include "types.hpp"
+
+#include <nlohmann/json.hpp>
+
+#include <mutex>
+#include <optional>
+#include <semaphore>
+#include <tuple>
+
+namespace vpd
+{
+/**
+ * @brief A class to process and publish VPD data.
+ *
+ * The class works on VPD and is mainly responsible for following tasks:
+ * 1) Select appropriate device tree and JSON. Reboot if required.
+ * 2) Get desired parser using parser factory.
+ * 3) Calling respective parser class to get parsed VPD.
+ * 4) Arranging VPD data under required interfaces.
+ * 5) Calling PIM to publish VPD.
+ *
+ * The class may also implement helper functions required for VPD handling.
+ */
+class Worker
+{
+  public:
+    /**
+     * List of deleted functions.
+     */
+    Worker(const Worker&);
+    Worker& operator=(const Worker&);
+    Worker(Worker&&) = delete;
+
+    /**
+     * @brief Constructor.
+     *
+     * In case the processing is not JSON based, no argument needs to be passed.
+     * Constructor will also, based on symlink pick the correct JSON and
+     * initialize the parsed JSON variable.
+     *
+     * @param[in] pathToConfigJSON - Path to the config JSON, if applicable.
+     *
+     * Note: Throws std::exception in case of construction failure. Caller needs
+     * to handle to detect successful object creation.
+     */
+    Worker(std::string pathToConfigJson = std::string());
+
+    /**
+     * @brief Destructor
+     */
+    ~Worker() = default;
+
+#ifdef IBM_SYSTEM
+    /**
+     * @brief API to perform initial setup before manager claims Bus name.
+     *
+     * Before BUS name for VPD-Manager is claimed, fitconfig whould be set for
+     * corret device tree, inventory JSON w.r.t system should be linked and
+     * system VPD should be on DBus.
+     */
+    void performInitialSetup();
+#endif
+
+    /**
+     * @brief An API to check if system VPD is already published.
+     *
+     * @return Status, true if system is already collected else false.
+     */
+    bool isSystemVPDOnDBus() const;
+
+    /**
+     * @brief API to process all FRUs presnt in config JSON file.
+     *
+     * This API based on config JSON passed/selected for the system, will
+     * trigger parser for all the FRUs and publish it on DBus.
+     *
+     * Note: Config JSON file path should be passed to worker class constructor
+     * to make use of this API.
+     *
+     */
+    void collectFrusFromJson();
+
+    /**
+     * @brief API to parse VPD data
+     *
+     * @param[in] i_vpdFilePath - Path to the VPD file.
+     */
+    types::VPDMapVariant parseVpdFile(const std::string& i_vpdFilePath);
+
+    /**
+     * @brief An API to populate DBus interfaces for a FRU.
+     *
+     * Note: Call this API to populate D-Bus. Also caller should handle empty
+     * objectInterfaceMap.
+     *
+     * @param[in] parsedVpdMap - Parsed VPD as a map.
+     * @param[out] objectInterfaceMap - Object and its interfaces map.
+     * @param[in] vpdFilePath - EEPROM path of FRU.
+     */
+    void populateDbus(const types::VPDMapVariant& parsedVpdMap,
+                      types::ObjectMap& objectInterfaceMap,
+                      const std::string& vpdFilePath);
+
+    /**
+     * @brief An API to delete FRU VPD over DBus.
+     *
+     * @param[in] i_dbusObjPath - Dbus object path of the FRU.
+     *
+     * @throw std::runtime_error if given input path is empty.
+     */
+    void deleteFruVpd(const std::string& i_dbusObjPath);
+
+    /**
+     * @brief API to get status of VPD collection process.
+     *
+     * @return - True when done, false otherwise.
+     */
+    inline bool isAllFruCollectionDone() const
+    {
+        return m_isAllFruCollected;
+    }
+
+    /**
+     * @brief API to get system config JSON object
+     *
+     * @return System config JSON object.
+     */
+    inline nlohmann::json getSysCfgJsonObj() const
+    {
+        return m_parsedJson;
+    }
+
+    /**
+     * @brief API to get active thread count.
+     *
+     * Each FRU is collected in a separate thread. This API gives the active
+     * thread collecting FRU's VPD at any given time.
+     *
+     * @return Count of active threads.
+     */
+    size_t getActiveThreadCount() const
+    {
+        return m_activeCollectionThreadCount;
+    }
+
+  private:
+    /**
+     * @brief An API to parse and publish a FRU VPD over D-Bus.
+     *
+     * Note: This API will handle all the exceptions internally and will only
+     * return status of parsing and publishing of VPD over D-Bus.
+     *
+     * @param[in] i_vpdFilePath - Path of file containing VPD.
+     * @return Tuple of status and file path. Status, true if successfull else
+     * false.
+     */
+    std::tuple<bool, std::string>
+        parseAndPublishVPD(const std::string& i_vpdFilePath);
+
+    /**
+     * @brief An API to set appropriate device tree and JSON.
+     *
+     * This API based on system chooses corresponding device tree and JSON.
+     * If device tree change is required, it updates the "fitconfig" and reboots
+     * the system. Else it is NOOP.
+     *
+     * @throw std::runtime_error
+     */
+    void setDeviceTreeAndJson();
+
+    /**
+     * @brief API to select system specific JSON.
+     *
+     * The API based on the IM value of VPD, will select appropriate JSON for
+     * the system. In case no system is found corresponding to the extracted IM
+     * value, error will be logged.
+     *
+     * @param[out] systemJson - System JSON name.
+     * @param[in] parsedVpdMap - Parsed VPD map.
+     */
+    void getSystemJson(std::string& systemJson,
+                       const types::VPDMapVariant& parsedVpdMap);
+
+    /**
+     * @brief An API to read IM value from VPD.
+     *
+     * Note: Throws exception in case of error. Caller need to handle.
+     *
+     * @param[in] parsedVpd - Parsed VPD.
+     */
+    std::string getIMValue(const types::IPZVpdMap& parsedVpd) const;
+
+    /**
+     * @brief An API to read HW version from VPD.
+     *
+     * Note: Throws exception in case of error. Caller need to handle.
+     *
+     * @param[in] parsedVpd - Parsed VPD.
+     */
+    std::string getHWVersion(const types::IPZVpdMap& parsedVpd) const;
+
+    /**
+     * @brief An API to parse given VPD file path.
+     *
+     * @param[in] vpdFilePath - EEPROM file path.
+     * @param[out] parsedVpd - Parsed VPD as a map.
+     */
+    void fillVPDMap(const std::string& vpdFilePath,
+                    types::VPDMapVariant& parsedVpd);
+
+    /**
+     * @brief An API to parse and publish system VPD on D-Bus.
+     *
+     * Note: Throws exception in case of invalid VPD format.
+     *
+     * @param[in] parsedVpdMap - Parsed VPD as a map.
+     */
+    void publishSystemVPD(const types::VPDMapVariant& parsedVpdMap);
+
+    /**
+     * @brief An API to process extrainterfaces w.r.t a FRU.
+     *
+     * @param[in] singleFru - JSON block for a single FRU.
+     * @param[out] interfaces - Map to hold interface along with its properties.
+     * @param[in] parsedVpdMap - Parsed VPD as a map.
+     */
+    void processExtraInterfaces(const nlohmann::json& singleFru,
+                                types::InterfaceMap& interfaces,
+                                const types::VPDMapVariant& parsedVpdMap);
+
+    /**
+     * @brief An API to process embedded and synthesized FRUs.
+     *
+     * @param[in] singleFru - FRU to be processed.
+     * @param[out] interfaces - Map to hold interface along with its properties.
+     */
+    void processEmbeddedAndSynthesizedFrus(const nlohmann::json& singleFru,
+                                           types::InterfaceMap& interfaces);
+
+    /**
+     * @brief An API to read process FRU based in CCIN.
+     *
+     * For some FRUs VPD can be processed only if the FRU has some specific
+     * value for CCIN. In case the value is not from that set, VPD for those
+     * FRUs can't be processed.
+     *
+     * @param[in] singleFru - Fru whose CCIN value needs to be matched.
+     * @param[in] parsedVpdMap - Parsed VPD map.
+     */
+    bool processFruWithCCIN(const nlohmann::json& singleFru,
+                            const types::VPDMapVariant& parsedVpdMap);
+
+    /**
+     * @brief API to process json's inherit flag.
+     *
+     * Inherit flag denotes that some property in the child FRU needs to be
+     * inherited from parent FRU.
+     *
+     * @param[in] parsedVpdMap - Parsed VPD as a map.
+     * @param[out] interfaces - Map to hold interface along with its properties.
+     */
+    void processInheritFlag(const types::VPDMapVariant& parsedVpdMap,
+                            types::InterfaceMap& interfaces);
+
+    /**
+     * @brief API to process json's "copyRecord" flag.
+     *
+     * copyRecord flag denotes if some record data needs to be copies in the
+     * given FRU.
+     *
+     * @param[in] singleFru - FRU being processed.
+     * @param[in] parsedVpdMap - Parsed VPD as a map.
+     * @param[out] interfaces - Map to hold interface along with its properties.
+     */
+    void processCopyRecordFlag(const nlohmann::json& singleFru,
+                               const types::VPDMapVariant& parsedVpdMap,
+                               types::InterfaceMap& interfaces);
+
+    /**
+     * @brief An API to populate IPZ VPD property map.
+     *
+     * @param[out] interfacePropMap - Map of interface and properties under it.
+     * @param[in] keyordValueMap - Keyword value map of IPZ VPD.
+     * @param[in] interfaceName - Name of the interface.
+     */
+    void populateIPZVPDpropertyMap(types::InterfaceMap& interfacePropMap,
+                                   const types::IPZKwdValueMap& keyordValueMap,
+                                   const std::string& interfaceName);
+
+    /**
+     * @brief An API to populate Kwd VPD property map.
+     *
+     * @param[in] keyordValueMap - Keyword value map of Kwd VPD.
+     * @param[out] interfaceMap - interface and property,value under it.
+     */
+    void populateKwdVPDpropertyMap(const types::KeywordVpdMap& keyordVPDMap,
+                                   types::InterfaceMap& interfaceMap);
+
+    /**
+     * @brief API to populate all required interface for a FRU.
+     *
+     * @param[in] interfaceJson - JSON containing interfaces to be populated.
+     * @param[out] interfaceMap - Map to hold populated interfaces.
+     * @param[in] parsedVpdMap - Parsed VPD as a map.
+     */
+    void populateInterfaces(const nlohmann::json& interfaceJson,
+                            types::InterfaceMap& interfaceMap,
+                            const types::VPDMapVariant& parsedVpdMap);
+
+    /**
+     * @brief Helper function to insert or merge in map.
+     *
+     * This method checks in the given inventory::InterfaceMap if the given
+     * interface key is existing or not. If the interface key already exists,
+     * given property map is inserted into it. If the key does'nt exist then
+     * given interface and property map pair is newly created. If the property
+     * present in propertymap already exist in the InterfaceMap, then the new
+     * property value is ignored.
+     *
+     * @param[in,out] interfaceMap - map object of type inventory::InterfaceMap
+     * only.
+     * @param[in] interface - Interface name.
+     * @param[in] property - new property map that needs to be emplaced.
+     */
+    void insertOrMerge(types::InterfaceMap& interfaceMap,
+                       const std::string& interface,
+                       types::PropertyMap&& property);
+
+    /**
+     * @brief Check if the given CPU is an IO only chip.
+     *
+     * The CPU is termed as IO, whose all of the cores are bad and can never be
+     * used. Those CPU chips can be used for IO purpose like connecting PCIe
+     * devices etc., The CPU whose every cores are bad, can be identified from
+     * the CP00 record's PG keyword, only if all of the 8 EQs' value equals
+     * 0xE7F9FF. (1EQ has 4 cores grouped together by sharing its cache memory.)
+     *
+     * @param [in] pgKeyword - PG Keyword of CPU.
+     * @return true if the given cpu is an IO, false otherwise.
+     */
+    bool isCPUIOGoodOnly(const std::string& pgKeyword);
+
+    /**
+     * @brief API to prime inventory Objects.
+     *
+     * @param[in] i_vpdFilePath - EEPROM file path.
+     * @return true if the prime inventory is success, false otherwise.
+     */
+    bool primeInventory(const std::string& i_vpdFilePath);
+
+    /**
+     * @brief API to process preAction(base_action) defined in config JSON.
+     *
+     * @note sequence of tags under any given flag of preAction is EXTREMELY
+     * important to ensure proper processing. The API will process all the
+     * nested items under the base action sequentially. Also if any of the tag
+     * processing fails, the code will not process remaining tags under the
+     * flag.
+     * ******** sample format **************
+     * fru EEPROM path: {
+     *     base_action: {
+     *         flag1: {
+     *           tag1: {
+     *            },
+     *           tag2: {
+     *            }
+     *         }
+     *         flag2: {
+     *           tags: {
+     *            }
+     *         }
+     *     }
+     * }
+     * *************************************
+     *
+     * @param[in] i_vpdFilePath - Path to the EEPROM file.
+     * @param[in] i_flagToProcess - To identify which flag(s) needs to be
+     * processed under PreAction tag of config JSON.
+     * @return Execution status.
+     */
+    bool processPreAction(const std::string& i_vpdFilePath,
+                          const std::string& i_flagToProcess);
+
+    /**
+     * @brief API to process postAction(base_action) defined in config JSON.
+     *
+     * @note Sequence of tags under any given flag of postAction is EXTREMELY
+     * important to ensure proper processing. The API will process all the
+     * nested items under the base action sequentially. Also if any of the tag
+     * processing fails, the code will not process remaining tags under the
+     * flag.
+     * ******** sample format **************
+     * fru EEPROM path: {
+     *     base_action: {
+     *         flag1: {
+     *           tag1: {
+     *            },
+     *           tag2: {
+     *            }
+     *         }
+     *         flag2: {
+     *           tags: {
+     *            }
+     *         }
+     *     }
+     * }
+     * *************************************
+     * Also, if post action is required to be processed only for FRUs with
+     * certain CCIN then CCIN list can be provided under flag.
+     *
+     * @param[in] i_vpdFruPath - Path to the EEPROM file.
+     * @param[in] i_flagToProcess - To identify which flag(s) needs to be
+     * processed under postAction tag of config JSON.
+     * @param[in] i_parsedVpd - Optional Parsed VPD map. If CCIN match is
+     * required.
+     * @return Execution status.
+     */
+    bool processPostAction(
+        const std::string& i_vpdFruPath, const std::string& i_flagToProcess,
+        const std::optional<types::VPDMapVariant> i_parsedVpd = std::nullopt);
+
+    /**
+     * @brief Function to enable and bring MUX out of idle state.
+     *
+     * This finds all the MUX defined in the system json and enables them by
+     * setting the holdidle parameter to 0.
+     *
+     * @throw std::runtime_error
+     */
+    void enableMuxChips();
+
+    /**
+     * @brief An API to perform backup or restore of VPD.
+     *
+     * @param[in,out] io_srcVpdMap - Source VPD map.
+     */
+    void performBackupAndRestore(types::VPDMapVariant& io_srcVpdMap);
+
+    /**
+     * @brief API to update "Functional" property.
+     *
+     * The API sets the default value for "Functional" property once if the
+     * property is not yet populated over DBus. As the property value is not
+     * controlled by the VPD-Collection process, if it is found already
+     * populated, the functions skips re-populating the property so that already
+     * existing value can be retained.
+     *
+     * @param[in] i_inventoryObjPath - Inventory path as read from config JSON.
+     * @param[in] io_interfaces - Map to hold all the interfaces for the FRU.
+     */
+    void processFunctionalProperty(const std::string& i_inventoryObjPath,
+                                   types::InterfaceMap& io_interfaces);
+
+    /**
+     * @brief API to update "enabled" property.
+     *
+     * The API sets the default value for "enabled" property once if the
+     * property is not yet populated over DBus. As the property value is not
+     * controlled by the VPD-Collection process, if it is found already
+     * populated, the functions skips re-populating the property so that already
+     * existing value can be retained.
+     *
+     * @param[in] i_inventoryObjPath - Inventory path as read from config JSON.
+     * @param[in] io_interfaces - Map to hold all the interfaces for the FRU.
+     */
+    void processEnabledProperty(const std::string& i_inventoryObjPath,
+                                types::InterfaceMap& io_interfaces);
+
+    /**
+     * @brief API to form asset tag string for the system.
+     *
+     * @param[in] i_parsedVpdMap - Parsed VPD map.
+     *
+     * @throw std::runtime_error
+     *
+     * @return - Formed asset tag string.
+     */
+    std::string
+        createAssetTagString(const types::VPDMapVariant& i_parsedVpdMap);
+
+    /**
+     * @brief API to prime system blueprint.
+     *
+     * The API will traverse the system config JSON and will prime all the FRU
+     * paths which qualifies for priming.
+     */
+    void primeSystemBlueprint();
+
+    /**
+     * @brief API to set symbolic link for system config JSON.
+     *
+     * Once correct device tree is set, symbolic link to the correct sytsem
+     * config JSON is set to be used in subsequent BMC boot.
+     *
+     * @param[in] i_systemJson - system config JSON.
+     */
+    void setJsonSymbolicLink(const std::string& i_systemJson);
+
+    // Parsed JSON file.
+    nlohmann::json m_parsedJson{};
+
+    // Hold if symlink is present or not.
+    bool m_isSymlinkPresent = false;
+
+    // Path to config JSON if applicable.
+    std::string& m_configJsonPath;
+
+    // Keeps track of active thread(s) doing VPD collection.
+    size_t m_activeCollectionThreadCount = 0;
+
+    // Holds status, if VPD collection has been done or not.
+    // Note: This variable does not give information about successfull or failed
+    // collection. It just states, if the VPD collection process is over or not.
+    bool m_isAllFruCollected = false;
+
+    // To distinguish the factory reset path.
+    bool m_isFactoryResetDone = false;
+
+    // Mutex to guard critical resource m_activeCollectionThreadCount.
+    std::mutex m_mutex;
+
+    // Counting semaphore to limit the number of threads.
+    std::counting_semaphore<constants::MAX_THREADS> m_semaphore{
+        constants::MAX_THREADS};
+};
+} // namespace vpd
