diff --git a/vpd-tool/README.md b/vpd-tool/README.md
new file mode 100644
index 0000000..4d02336
--- /dev/null
+++ b/vpd-tool/README.md
@@ -0,0 +1,6 @@
+# VPD Tool Overview
+
+VPD Tool is designed for managing BMC system FRU's Vital Product Data(VPD). It
+provides command line interface to read and write FRU's VPD. More information
+can be found
+[here](https://github.ibm.com/openbmc/openbmc/wiki/VPD-TOOL-HELPER).
diff --git a/vpd-tool/include/tool_constants.hpp b/vpd-tool/include/tool_constants.hpp
new file mode 100644
index 0000000..6e89957
--- /dev/null
+++ b/vpd-tool/include/tool_constants.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <cstdint>
+
+namespace vpd
+{
+namespace constants
+{
+static constexpr auto KEYWORD_SIZE = 2;
+static constexpr auto RECORD_SIZE = 4;
+static constexpr auto INDENTATION = 4;
+static constexpr auto SUCCESS = 0;
+static constexpr auto FAILURE = -1;
+
+// To be explicitly used for string comparison.
+static constexpr auto STR_CMP_SUCCESS = 0;
+
+constexpr auto inventoryManagerService =
+    "xyz.openbmc_project.Inventory.Manager";
+constexpr auto baseInventoryPath = "/xyz/openbmc_project/inventory";
+constexpr auto ipzVpdInfPrefix = "com.ibm.ipzvpd.";
+
+constexpr auto vpdManagerService = "com.ibm.VPD.Manager";
+constexpr auto vpdManagerObjectPath = "/com/ibm/VPD/Manager";
+constexpr auto vpdManagerInfName = "com.ibm.VPD.Manager";
+constexpr auto inventoryItemInf = "xyz.openbmc_project.Inventory.Item";
+constexpr auto kwdVpdInf = "com.ibm.ipzvpd.VINI";
+constexpr auto locationCodeInf = "com.ibm.ipzvpd.Location";
+constexpr auto assetInf = "xyz.openbmc_project.Inventory.Decorator.Asset";
+constexpr auto objectMapperService = "xyz.openbmc_project.ObjectMapper";
+constexpr auto objectMapperObjectPath = "/xyz/openbmc_project/object_mapper";
+constexpr auto objectMapperInfName = "xyz.openbmc_project.ObjectMapper";
+} // namespace constants
+} // namespace vpd
diff --git a/vpd-tool/include/tool_types.hpp b/vpd-tool/include/tool_types.hpp
new file mode 100644
index 0000000..1e9ff7d
--- /dev/null
+++ b/vpd-tool/include/tool_types.hpp
@@ -0,0 +1,83 @@
+#pragma once
+
+#include <sdbusplus/message/types.hpp>
+
+#include <cstdint>
+#include <tuple>
+#include <variant>
+#include <vector>
+
+namespace vpd
+{
+namespace types
+{
+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>>
+ >;
+
+//IpzType contains tuple of <Record, Keyword>
+using IpzType = std::tuple<std::string, std::string>;
+
+//ReadVpdParams either of IPZ or keyword format
+using ReadVpdParams = std::variant<IpzType, std::string>;
+
+//KwData contains tuple of <keywordName, KeywordValue>
+using KwData = std::tuple<std::string, BinaryVector>;
+
+//IpzData contains tuple of <RecordName, KeywordName, KeywordValue>
+using IpzData = std::tuple<std::string, std::string, BinaryVector>;
+
+//WriteVpdParams either of IPZ or keyword format
+using WriteVpdParams = std::variant<IpzData, KwData>;
+// Return type of ObjectMapper GetObject API
+using MapperGetObject = std::map<std::string,std::vector<std::string>>;
+
+// Table row data
+using TableRowData = std::vector<std::string>;
+
+// Type used to populate table data
+using TableInputData = std::vector<TableRowData>;
+
+// A table column name-size pair
+using TableColumnNameSizePair = std::pair<std::string, std::size_t>;
+
+enum UserOption
+{
+    Exit,
+    UseBackupDataForAll,
+    UseSystemBackplaneDataForAll,
+    MoreOptions,
+    UseBackupDataForCurrent,
+    UseSystemBackplaneDataForCurrent,
+    NewValueOnBoth,
+    SkipCurrent
+};
+
+} // namespace types
+} // namespace vpd
diff --git a/vpd-tool/include/tool_utils.hpp b/vpd-tool/include/tool_utils.hpp
new file mode 100644
index 0000000..4d650c1
--- /dev/null
+++ b/vpd-tool/include/tool_utils.hpp
@@ -0,0 +1,726 @@
+#pragma once
+
+#include "tool_constants.hpp"
+#include "tool_types.hpp"
+
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/exception.hpp>
+
+#include <fstream>
+#include <iostream>
+
+namespace vpd
+{
+namespace utils
+{
+/**
+ * @brief An API to read property from Dbus.
+ *
+ * API reads the property value for the specified interface and object path from
+ * the given Dbus service.
+ *
+ * The caller of the API needs to validate the validity and correctness of the
+ * type and value of data returned. The API will just fetch and return 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] i_serviceName - Name of the Dbus service.
+ * @param[in] i_objectPath - Object path under the service.
+ * @param[in] i_interface - Interface under which property exist.
+ * @param[in] i_property - Property whose value is to be read.
+ *
+ * @return - Value read from Dbus.
+ *
+ * @throw std::runtime_error
+ */
+inline types::DbusVariantType readDbusProperty(
+    const std::string& i_serviceName, const std::string& i_objectPath,
+    const std::string& i_interface, const std::string& i_property)
+{
+    types::DbusVariantType l_propertyValue;
+
+    // Mandatory fields to make a dbus call.
+    if (i_serviceName.empty() || i_objectPath.empty() || i_interface.empty() ||
+        i_property.empty())
+    {
+        // TODO: Enable logging when verbose is enabled.
+        /*std::cout << "One of the parameter to make Dbus read call is empty."
+                  << std::endl;*/
+        throw std::runtime_error("Empty Parameter");
+    }
+
+    try
+    {
+        auto l_bus = sdbusplus::bus::new_default();
+        auto l_method =
+            l_bus.new_method_call(i_serviceName.c_str(), i_objectPath.c_str(),
+                                  "org.freedesktop.DBus.Properties", "Get");
+        l_method.append(i_interface, i_property);
+
+        auto result = l_bus.call(l_method);
+        result.read(l_propertyValue);
+    }
+    catch (const sdbusplus::exception::SdBusError& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        // std::cout << std::string(l_ex.what()) << std::endl;
+        throw std::runtime_error(std::string(l_ex.what()));
+    }
+    return l_propertyValue;
+}
+
+/**
+ * @brief An API to print json data on stdout.
+ *
+ * @param[in] i_jsonData - JSON object.
+ */
+inline void printJson(const nlohmann::json& i_jsonData)
+{
+    try
+    {
+        std::cout << i_jsonData.dump(constants::INDENTATION) << std::endl;
+    }
+    catch (const nlohmann::json::type_error& l_ex)
+    {
+        throw std::runtime_error(
+            "Failed to dump JSON data, error: " + std::string(l_ex.what()));
+    }
+}
+
+/**
+ * @brief An API to convert binary value into ascii/hex representation.
+ *
+ * If given data contains printable characters, ASCII formated string value of
+ * the input data will be returned. Otherwise if the data has any non-printable
+ * value, returns the hex represented value of the given data in string format.
+ *
+ * @param[in] i_keywordValue - Data in binary format.
+ *
+ * @throw - Throws std::bad_alloc or std::terminate in case of error.
+ *
+ * @return - Returns the converted string value.
+ */
+inline std::string getPrintableValue(const types::BinaryVector& i_keywordValue)
+{
+    bool l_allPrintable =
+        std::all_of(i_keywordValue.begin(), i_keywordValue.end(),
+                    [](const auto& l_byte) { return std::isprint(l_byte); });
+
+    std::ostringstream l_oss;
+    if (l_allPrintable)
+    {
+        l_oss << std::string(i_keywordValue.begin(), i_keywordValue.end());
+    }
+    else
+    {
+        l_oss << "0x";
+        for (const auto& l_byte : i_keywordValue)
+        {
+            l_oss << std::setfill('0') << std::setw(2) << std::hex
+                  << static_cast<int>(l_byte);
+        }
+    }
+
+    return l_oss.str();
+}
+
+/**
+ * @brief API to read keyword's value from hardware.
+ *
+ * This API reads keyword's value by requesting DBus service(vpd-manager) who
+ * hosts the 'ReadKeyword' method to read keyword's value.
+ *
+ * @param[in] i_eepromPath - EEPROM file path.
+ * @param[in] i_paramsToReadData - Property whose value has to be read.
+ *
+ * @return - Value read from hardware
+ *
+ * @throw std::runtime_error, sdbusplus::exception::SdBusError
+ */
+inline types::DbusVariantType
+    readKeywordFromHardware(const std::string& i_eepromPath,
+                            const types::ReadVpdParams i_paramsToReadData)
+{
+    if (i_eepromPath.empty())
+    {
+        throw std::runtime_error("Empty EEPROM path");
+    }
+
+    try
+    {
+        types::DbusVariantType l_propertyValue;
+
+        auto l_bus = sdbusplus::bus::new_default();
+
+        auto l_method = l_bus.new_method_call(
+            constants::vpdManagerService, constants::vpdManagerObjectPath,
+            constants::vpdManagerInfName, "ReadKeyword");
+
+        l_method.append(i_eepromPath, i_paramsToReadData);
+        auto l_result = l_bus.call(l_method);
+
+        l_result.read(l_propertyValue);
+
+        return l_propertyValue;
+    }
+    catch (const sdbusplus::exception::SdBusError& l_error)
+    {
+        throw;
+    }
+}
+
+/**
+ * @brief API to save keyword's value on file.
+ *
+ * API writes keyword's value on the given file path. If the data is in hex
+ * format, API strips '0x' and saves the value on the given file.
+ *
+ * @param[in] i_filePath - File path.
+ * @param[in] i_keywordValue - Keyword's value.
+ *
+ * @return - true on successfully writing to file, false otherwise.
+ */
+inline bool saveToFile(const std::string& i_filePath,
+                       const std::string& i_keywordValue)
+{
+    bool l_returnStatus = false;
+
+    if (i_keywordValue.empty())
+    {
+        // ToDo: log only when verbose is enabled
+        std::cerr << "Save to file[ " << i_filePath
+                  << "] failed, reason: Empty keyword's value received"
+                  << std::endl;
+        return l_returnStatus;
+    }
+
+    std::string l_keywordValue{i_keywordValue};
+    if (i_keywordValue.substr(0, 2).compare("0x") == constants::STR_CMP_SUCCESS)
+    {
+        l_keywordValue = i_keywordValue.substr(2);
+    }
+
+    std::ofstream l_outPutFileStream;
+    l_outPutFileStream.exceptions(
+        std::ifstream::badbit | std::ifstream::failbit);
+    try
+    {
+        l_outPutFileStream.open(i_filePath);
+
+        if (l_outPutFileStream.is_open())
+        {
+            l_outPutFileStream.write(l_keywordValue.c_str(),
+                                     l_keywordValue.size());
+            l_returnStatus = true;
+        }
+        else
+        {
+            // ToDo: log only when verbose is enabled
+            std::cerr << "Error opening output file " << i_filePath
+                      << std::endl;
+        }
+    }
+    catch (const std::ios_base::failure& l_ex)
+    {
+        // ToDo: log only when verbose is enabled
+        std::cerr
+            << "Failed to write to file: " << i_filePath
+            << ", either base folder path doesn't exist or internal error occured, error: "
+            << l_ex.what() << '\n';
+    }
+
+    return l_returnStatus;
+}
+
+/**
+ * @brief API to print data in JSON format on console
+ *
+ * @param[in] i_fruPath - FRU path.
+ * @param[in] i_keywordName - Keyword name.
+ * @param[in] i_keywordStrValue - Keyword's value.
+ */
+inline void displayOnConsole(const std::string& i_fruPath,
+                             const std::string& i_keywordName,
+                             const std::string& i_keywordStrValue)
+{
+    nlohmann::json l_resultInJson = nlohmann::json::object({});
+    nlohmann::json l_keywordValInJson = nlohmann::json::object({});
+
+    l_keywordValInJson.emplace(i_keywordName, i_keywordStrValue);
+    l_resultInJson.emplace(i_fruPath, l_keywordValInJson);
+
+    printJson(l_resultInJson);
+}
+
+/**
+ * @brief API to write keyword's value.
+ *
+ * This API writes keyword's value by requesting DBus service(vpd-manager) who
+ * hosts the 'UpdateKeyword' method to update keyword's value.
+ *
+ * @param[in] i_vpdPath - EEPROM or object path, where keyword is present.
+ * @param[in] i_paramsToWriteData - Data required to update keyword's value.
+ *
+ * @return - Number of bytes written on success, -1 on failure.
+ *
+ * @throw - std::runtime_error, sdbusplus::exception::SdBusError
+ */
+inline int writeKeyword(const std::string& i_vpdPath,
+                        const types::WriteVpdParams& i_paramsToWriteData)
+{
+    if (i_vpdPath.empty())
+    {
+        throw std::runtime_error("Empty path");
+    }
+
+    int l_rc = constants::FAILURE;
+    auto l_bus = sdbusplus::bus::new_default();
+
+    auto l_method = l_bus.new_method_call(
+        constants::vpdManagerService, constants::vpdManagerObjectPath,
+        constants::vpdManagerInfName, "UpdateKeyword");
+
+    l_method.append(i_vpdPath, i_paramsToWriteData);
+    auto l_result = l_bus.call(l_method);
+
+    l_result.read(l_rc);
+    return l_rc;
+}
+
+/**
+ * @brief API to write keyword's value on hardware.
+ *
+ * This API writes keyword's value by requesting DBus service(vpd-manager) who
+ * hosts the 'WriteKeywordOnHardware' method to update keyword's value.
+ *
+ * Note: This API updates keyword's value only on the given hardware path, any
+ * backup or redundant EEPROM (if exists) paths won't get updated.
+ *
+ * @param[in] i_eepromPath - EEPROM where keyword is present.
+ * @param[in] i_paramsToWriteData - Data required to update keyword's value.
+ *
+ * @return - Number of bytes written on success, -1 on failure.
+ *
+ * @throw - std::runtime_error, sdbusplus::exception::SdBusError
+ */
+inline int
+    writeKeywordOnHardware(const std::string& i_eepromPath,
+                           const types::WriteVpdParams& i_paramsToWriteData)
+{
+    if (i_eepromPath.empty())
+    {
+        throw std::runtime_error("Empty path");
+    }
+
+    int l_rc = constants::FAILURE;
+    auto l_bus = sdbusplus::bus::new_default();
+
+    auto l_method = l_bus.new_method_call(
+        constants::vpdManagerService, constants::vpdManagerObjectPath,
+        constants::vpdManagerInfName, "WriteKeywordOnHardware");
+
+    l_method.append(i_eepromPath, i_paramsToWriteData);
+    auto l_result = l_bus.call(l_method);
+
+    l_result.read(l_rc);
+
+    if (l_rc > 0)
+    {
+        std::cout << "Data updated successfully " << std::endl;
+    }
+    return l_rc;
+}
+
+/**
+ * @brief API to get data in binary format.
+ *
+ * This API converts given string value into array of binary data.
+ *
+ * @param[in] i_value - Input data.
+ *
+ * @return - Array of binary data on success, throws as exception in case
+ * of any error.
+ *
+ * @throw std::runtime_error, std::out_of_range, std::bad_alloc,
+ * std::invalid_argument
+ */
+inline types::BinaryVector convertToBinary(const std::string& i_value)
+{
+    if (i_value.empty())
+    {
+        throw std::runtime_error(
+            "Provide a valid hexadecimal input. (Ex. 0x30313233)");
+    }
+
+    std::vector<uint8_t> l_binaryValue{};
+
+    if (i_value.substr(0, 2).compare("0x") == constants::STR_CMP_SUCCESS)
+    {
+        if (i_value.length() % 2 != 0)
+        {
+            throw std::runtime_error(
+                "Write option accepts 2 digit hex numbers. (Ex. 0x1 "
+                "should be given as 0x01).");
+        }
+
+        auto l_value = i_value.substr(2);
+
+        if (l_value.empty())
+        {
+            throw std::runtime_error(
+                "Provide a valid hexadecimal input. (Ex. 0x30313233)");
+        }
+
+        if (l_value.find_first_not_of("0123456789abcdefABCDEF") !=
+            std::string::npos)
+        {
+            throw std::runtime_error("Provide a valid hexadecimal input.");
+        }
+
+        for (size_t l_pos = 0; l_pos < l_value.length(); l_pos += 2)
+        {
+            uint8_t l_byte = static_cast<uint8_t>(
+                std::stoi(l_value.substr(l_pos, 2), nullptr, 16));
+            l_binaryValue.push_back(l_byte);
+        }
+    }
+    else
+    {
+        l_binaryValue.assign(i_value.begin(), i_value.end());
+    }
+    return l_binaryValue;
+}
+
+/**
+ * @brief API to parse respective JSON.
+ *
+ * @param[in] i_pathToJson - Path to JSON.
+ *
+ * @return Parsed JSON, throws exception in case of error.
+ *
+ * @throw std::runtime_error
+ */
+inline nlohmann::json getParsedJson(const std::string& i_pathToJson)
+{
+    if (i_pathToJson.empty())
+    {
+        throw std::runtime_error("Path to JSON is missing");
+    }
+
+    std::error_code l_ec;
+    if (!std::filesystem::exists(i_pathToJson, l_ec))
+    {
+        std::string l_message{
+            "file system call failed for file: " + i_pathToJson};
+
+        if (l_ec)
+        {
+            l_message += ", error: " + l_ec.message();
+        }
+        throw std::runtime_error(l_message);
+    }
+
+    if (std::filesystem::is_empty(i_pathToJson, l_ec))
+    {
+        throw std::runtime_error("Empty file: " + i_pathToJson);
+    }
+    else if (l_ec)
+    {
+        throw std::runtime_error("is_empty file system call failed for file: " +
+                                 i_pathToJson + ", error: " + l_ec.message());
+    }
+
+    std::ifstream l_jsonFile(i_pathToJson);
+    if (!l_jsonFile)
+    {
+        throw std::runtime_error("Failed to access Json path: " + i_pathToJson);
+    }
+
+    try
+    {
+        return nlohmann::json::parse(l_jsonFile);
+    }
+    catch (const nlohmann::json::parse_error& l_ex)
+    {
+        throw std::runtime_error("Failed to parse JSON file: " + i_pathToJson);
+    }
+}
+
+/**
+ * @brief API to get list of interfaces under a given object path.
+ *
+ * Given a DBus object path, this API returns a map of service -> implemented
+ * interface(s) under that object path. This API calls DBus method GetObject
+ * hosted by ObjectMapper DBus service.
+ *
+ * @param[in] i_objectPath - DBus object path.
+ * @param[in] i_constrainingInterfaces - An array of result set constraining
+ * interfaces.
+ *
+ * @return On success, returns a map of service -> implemented interface(s),
+ * else returns an empty map. The caller of this
+ * API should check for empty map.
+ */
+inline types::MapperGetObject GetServiceInterfacesForObject(
+    const std::string& i_objectPath,
+    const std::vector<std::string>& i_constrainingInterfaces) noexcept
+{
+    types::MapperGetObject l_serviceInfMap;
+    if (i_objectPath.empty())
+    {
+        // TODO: log only when verbose is enabled
+        std::cerr << "Object path is empty." << std::endl;
+        return l_serviceInfMap;
+    }
+
+    try
+    {
+        auto l_bus = sdbusplus::bus::new_default();
+        auto l_method = l_bus.new_method_call(
+            constants::objectMapperService, constants::objectMapperObjectPath,
+            constants::objectMapperInfName, "GetObject");
+
+        l_method.append(i_objectPath, i_constrainingInterfaces);
+
+        auto l_result = l_bus.call(l_method);
+        l_result.read(l_serviceInfMap);
+    }
+    catch (const sdbusplus::exception::SdBusError& l_ex)
+    {
+        // TODO: log only when verbose is enabled
+        // std::cerr << std::string(l_ex.what()) << std::endl;
+    }
+    return l_serviceInfMap;
+}
+
+/** @brief API to get list of sub tree paths for a given object path
+ *
+ * Given a DBus object path, this API returns a list of object paths under that
+ * object path in the DBus tree. This API calls DBus method GetSubTreePaths
+ * hosted by ObjectMapper DBus service.
+ *
+ * @param[in] i_objectPath - DBus object path.
+ * @param[in] i_constrainingInterfaces - An array of result set constraining
+ * interfaces.
+ * @param[in] i_depth - The maximum subtree depth for which results should be
+ * fetched. For unconstrained fetches use a depth of zero.
+ *
+ * @return On success, returns a std::vector<std::string> of object paths in
+ * Phosphor Inventory Manager DBus service's tree, else returns an empty vector.
+ * The caller of this API should check for empty vector.
+ */
+inline std::vector<std::string> GetSubTreePaths(
+    const std::string i_objectPath, const int i_depth = 0,
+    const std::vector<std::string>& i_constrainingInterfaces = {}) noexcept
+{
+    std::vector<std::string> l_objectPaths;
+
+    try
+    {
+        auto l_bus = sdbusplus::bus::new_default();
+        auto l_method = l_bus.new_method_call(
+            constants::objectMapperService, constants::objectMapperObjectPath,
+            constants::objectMapperInfName, "GetSubTreePaths");
+
+        l_method.append(i_objectPath, i_depth, i_constrainingInterfaces);
+
+        auto l_result = l_bus.call(l_method);
+        l_result.read(l_objectPaths);
+    }
+    catch (const sdbusplus::exception::SdBusError& l_ex)
+    {
+        // TODO: log only when verbose is enabled
+        std::cerr << std::string(l_ex.what()) << std::endl;
+    }
+    return l_objectPaths;
+}
+
+/**
+ * @brief A class to print data in tabular format
+ *
+ * This class implements methods to print data in a two dimensional tabular
+ * format. All entries in the table must be in string format.
+ *
+ */
+class Table
+{
+    class Column : public types::TableColumnNameSizePair
+    {
+      public:
+        /**
+         * @brief API to get the name of the Column
+         *
+         * @return Name of the Column.
+         */
+        const std::string& Name() const
+        {
+            return this->first;
+        }
+
+        /**
+         * @brief API to get the width of the Column
+         *
+         * @return Width of the Column.
+         */
+        std::size_t Width() const
+        {
+            return this->second;
+        }
+    };
+
+    // Current width of the table
+    std::size_t m_currentWidth;
+
+    // Character to be used as fill character between entries
+    char m_fillCharacter;
+
+    // Separator character to be used between columns
+    char m_separator;
+
+    // Array of columns
+    std::vector<Column> m_columns;
+
+    /**
+     * @brief API to Print Header
+     *
+     * Header line prints the names of the Column headers separated by the
+     * specified separator character and spaced accordingly.
+     *
+     * @throw std::out_of_range, std::length_error, std::bad_alloc
+     */
+    void PrintHeader() const
+    {
+        for (const auto& l_column : m_columns)
+        {
+            PrintEntry(l_column.Name(), l_column.Width());
+        }
+        std::cout << m_separator << std::endl;
+    }
+
+    /**
+     * @brief API to Print Horizontal Line
+     *
+     * A horizontal line is a sequence of '*'s.
+     *
+     * @throw std::out_of_range, std::length_error, std::bad_alloc
+     */
+    void PrintHorizontalLine() const
+    {
+        std::cout << std::string(m_currentWidth, '*') << std::endl;
+    }
+
+    /**
+     * @brief API to print an entry in the table
+     *
+     * An entry is a separator character followed by the text to print.
+     * The text is centre-aligned.
+     *
+     * @param[in] i_text - text to print
+     * @param[in] i_columnWidth - width of the column
+     *
+     * @throw std::out_of_range, std::length_error, std::bad_alloc
+     */
+    void PrintEntry(const std::string& i_text, std::size_t i_columnWidth) const
+    {
+        const std::size_t l_textLength{i_text.length()};
+
+        constexpr std::size_t l_minFillChars{3};
+        const std::size_t l_numFillChars =
+            ((l_textLength >= i_columnWidth ? l_minFillChars
+                                            : i_columnWidth - l_textLength)) -
+            1; // -1 for the separator character
+
+        const unsigned l_oddFill = l_numFillChars % 2;
+
+        std::cout << m_separator
+                  << std::string((l_numFillChars / 2) + l_oddFill,
+                                 m_fillCharacter)
+                  << i_text << std::string(l_numFillChars / 2, m_fillCharacter);
+    }
+
+  public:
+    /**
+     * @brief Table Constructor
+     *
+     * Parameterized constructor for a Table object
+     *
+     */
+    constexpr explicit Table(const char i_fillCharacter = ' ',
+                             const char i_separator = '|') noexcept :
+        m_currentWidth{0}, m_fillCharacter{i_fillCharacter},
+        m_separator{i_separator}
+    {}
+
+    // deleted methods
+    Table(const Table&) = delete;
+    Table operator=(const Table&) = delete;
+    Table(const Table&&) = delete;
+    Table operator=(const Table&&) = delete;
+
+    ~Table() = default;
+
+    /**
+     * @brief API to add column to Table
+     *
+     * @param[in] i_name - Name of the column.
+     *
+     * @param[in] i_width - Width to allocate for the column.
+     *
+     * @return On success returns 0, otherwise returns -1.
+     */
+    int AddColumn(const std::string& i_name, std::size_t i_width)
+    {
+        if (i_width < i_name.length())
+            return constants::FAILURE;
+        m_columns.emplace_back(types::TableColumnNameSizePair(i_name, i_width));
+        m_currentWidth += i_width;
+        return constants::SUCCESS;
+    }
+
+    /**
+     * @brief API to print the Table to console.
+     *
+     * This API prints the table data to console.
+     *
+     * @param[in] i_tableData - The data to be printed.
+     *
+     * @return On success returns 0, otherwise returns -1.
+     *
+     * @throw std::out_of_range, std::length_error, std::bad_alloc
+     */
+    int Print(const types::TableInputData& i_tableData) const
+    {
+        PrintHorizontalLine();
+        PrintHeader();
+        PrintHorizontalLine();
+
+        // print the table data
+        for (const auto& l_row : i_tableData)
+        {
+            unsigned l_columnNumber{0};
+
+            // number of columns in input data is greater than the number of
+            // columns specified in Table
+            if (l_row.size() > m_columns.size())
+            {
+                return constants::FAILURE;
+            }
+
+            for (const auto& l_entry : l_row)
+            {
+                PrintEntry(l_entry, m_columns[l_columnNumber].Width());
+
+                ++l_columnNumber;
+            }
+            std::cout << m_separator << std::endl;
+        }
+        PrintHorizontalLine();
+        return constants::SUCCESS;
+    }
+};
+
+} // namespace utils
+} // namespace vpd
diff --git a/vpd-tool/include/vpd_tool.hpp b/vpd-tool/include/vpd_tool.hpp
new file mode 100644
index 0000000..80be8e5
--- /dev/null
+++ b/vpd-tool/include/vpd_tool.hpp
@@ -0,0 +1,287 @@
+#pragma once
+
+#include "tool_utils.hpp"
+
+#include <nlohmann/json.hpp>
+
+#include <optional>
+#include <string>
+
+namespace vpd
+{
+/**
+ * @brief Class to support operations on VPD.
+ *
+ * The class provides API's to,
+ * Read keyword value from DBus/hardware.
+ * Update keyword value to DBus/hardware.
+ * Dump DBus object's critical information.
+ * Fix system VPD if any mismatch between DBus and hardware data.
+ * Reset specific system VPD keywords to its default value.
+ * Force VPD collection for hardware.
+ */
+class VpdTool
+{
+  private:
+    /**
+     * @brief Get specific properties of a FRU in JSON format.
+     *
+     * For a given object path of a FRU, this API returns the following
+     * properties of the FRU in JSON format:
+     * - Pretty Name, Location Code, Sub Model
+     * - SN, PN, CC, FN, DR keywords under VINI record.
+     *
+     * @param[in] i_objectPath - DBus object path
+     *
+     * @return On success, returns the properties of the FRU in JSON format,
+     * otherwise returns an empty JSON.
+     * If FRU's "Present" property is false, this API returns an empty JSON.
+     * Note: The caller of this API should handle empty JSON.
+     *
+     * @throw json::exception
+     */
+    nlohmann::json getFruProperties(const std::string& i_objectPath) const;
+
+    /**
+     * @brief Get any inventory property in JSON.
+     *
+     * API to get any property of a FRU in JSON format. Given an object path,
+     * interface and property name, this API does a D-Bus read property on PIM
+     * to get the value of that property and returns it in JSON format. This API
+     * returns empty JSON in case of failure. The caller of the API must check
+     * for empty JSON.
+     *
+     * @param[in] i_objectPath - DBus object path
+     * @param[in] i_interface - Interface name
+     * @param[in] i_propertyName - Property name
+     *
+     * @return On success, returns the property and its value in JSON format,
+     * otherwise return empty JSON.
+     * {"SN" : "ABCD"}
+     */
+    template <typename PropertyType>
+    nlohmann::json getInventoryPropertyJson(
+        const std::string& i_objectPath, const std::string& i_interface,
+        const std::string& i_propertyName) const noexcept;
+
+    /**
+     * @brief Get the "type" property for a FRU.
+     *
+     * Given a FRU path, and parsed System Config JSON, this API returns the
+     * "type" property for the FRU in JSON format. This API gets
+     * these properties from Phosphor Inventory Manager.
+     *
+     * @param[in] i_objectPath - DBus object path.
+     *
+     * @return On success, returns the "type" property in JSON
+     * format, otherwise returns empty JSON. The caller of this API should
+     * handle empty JSON.
+     */
+    nlohmann::json
+        getFruTypeProperty(const std::string& i_objectPath) const noexcept;
+
+    /**
+     * @brief Check if a FRU is present in the system.
+     *
+     * Given a FRU's object path, this API checks if the FRU is present in the
+     * system by reading the "Present" property of the FRU.
+     *
+     * @param[in] i_objectPath - DBus object path.
+     *
+     * @return true if FRU's "Present" property is true, false otherwise.
+     */
+    bool isFruPresent(const std::string& i_objectPath) const noexcept;
+
+    /**
+     * @brief An API to get backup-restore config JSON of the system.
+     *
+     * API gets this file by prasing system config JSON file and reading
+     * backupRestoreConfigPath tag.
+     *
+     * @return On success returns valid JSON object, otherwise returns empty
+     * JSON object.
+     *
+     * Note: The caller of this API should verify, is received JSON object is
+     * empty or not.
+     */
+    nlohmann::json getBackupRestoreCfgJsonObj() const noexcept;
+
+    /**
+     * @brief Prints the user options for fix system VPD command.
+     *
+     * @param[in] i_option - Option to use.
+     */
+    void printFixSystemVpdOption(
+        const types::UserOption& i_option) const noexcept;
+
+    /**
+     * @brief API to update source and destination keyword's value.
+     *
+     * API fetches source and destination keyword's value,
+     * for each keyword entries found in the input JSON object and updates the
+     * JSON object. If the path(source / destination) in JSON object is
+     * inventory object path, API sends the request to Inventory.Manager DBus
+     * service. Otherwise if its a hardware path, API sends the request to
+     * vpd-manager DBus service to get the keyword's value.
+     *
+     * @param[in,out] io_parsedJsonObj - Parsed JSON object.
+     *
+     * @return true on success, false in case of any error.
+     */
+    bool fetchKeywordInfo(nlohmann::json& io_parsedJsonObj) const noexcept;
+
+    /**
+     * @brief API to print system VPD keyword's information.
+     *
+     * The API prints source and destination keyword's information in the table
+     * format, found in the JSON object.
+     *
+     * @param[in] i_parsedJsonObj - Parsed JSON object.
+     */
+    void printSystemVpd(const nlohmann::json& i_parsedJsonObj) const noexcept;
+
+    /**
+     * @brief API to update keyword's value.
+     *
+     * API iterates the given JSON object for all record-keyword pairs, if there
+     * is any mismatch between source and destination keyword's value, API calls
+     * the utils::writeKeyword API to update keyword's value.
+     *
+     * Note: writeKeyword API, internally updates primary, backup, redundant
+     * EEPROM paths(if exists) with the given keyword's value.
+     *
+     * @param i_parsedJsonObj - Parsed JSON object.
+     * @param i_useBackupData - Specifies whether to use source or destination
+     * keyword's value to update the keyword's value.
+     *
+     * @return On success return 0, otherwise return -1.
+     */
+    int updateAllKeywords(const nlohmann::json& i_parsedJsonObj,
+                          bool i_useBackupData) const noexcept;
+
+    /**
+     * @brief API to handle more option for fix system VPD command.
+     *
+     * @param i_parsedJsonObj - Parsed JSON object.
+     *
+     * @return On success return 0, otherwise return -1.
+     */
+    int handleMoreOption(const nlohmann::json& i_parsedJsonObj) const noexcept;
+
+  public:
+    /**
+     * @brief Read keyword value.
+     *
+     * API to read VPD keyword's value from the given input path.
+     * If the provided i_onHardware option is true, read keyword's value from
+     * the hardware. Otherwise read keyword's value from DBus.
+     *
+     * @param[in] i_vpdPath - DBus object path or EEPROM path.
+     * @param[in] i_recordName - Record name.
+     * @param[in] i_keywordName - Keyword name.
+     * @param[in] i_onHardware - True if i_vpdPath is EEPROM path, false
+     * otherwise.
+     * @param[in] i_fileToSave - File path to save keyword's value, if not given
+     * result will redirect to a console.
+     *
+     * @return On success return 0, otherwise return -1.
+     */
+    int readKeyword(const std::string& i_vpdPath,
+                    const std::string& i_recordName,
+                    const std::string& i_keywordName, const bool i_onHardware,
+                    const std::string& i_fileToSave = {});
+
+    /**
+     * @brief Dump the given inventory object in JSON format to console.
+     *
+     * For a given object path of a FRU, this API dumps the following properties
+     * of the FRU in JSON format to console:
+     * - Pretty Name, Location Code, Sub Model
+     * - SN, PN, CC, FN, DR keywords under VINI record.
+     * If the FRU's "Present" property is not true, the above properties are not
+     * dumped to console.
+     *
+     * @param[in] i_fruPath - DBus object path.
+     *
+     * @return On success returns 0, otherwise returns -1.
+     */
+    int dumpObject(std::string i_fruPath) const noexcept;
+
+    /**
+     * @brief API to fix system VPD keywords.
+     *
+     * The API to fix the system VPD keywords. Mainly used when there
+     * is a mismatch between the primary and backup(secondary) VPD. User can
+     * choose option to update all primary keywords value with corresponding
+     * backup keywords value or can choose primary keyword value to sync
+     * secondary VPD. Otherwise, user can also interactively choose different
+     * action for individual keyword.
+     *
+     * @return On success returns 0, otherwise returns -1.
+     */
+    int fixSystemVpd() const noexcept;
+
+    /**
+     * @brief Write keyword's value.
+     *
+     * API to update VPD keyword's value to the given input path.
+     * If i_onHardware value in true, i_vpdPath is considered has hardware path
+     * otherwise it will be considered as DBus object path.
+     *
+     * For provided DBus object path both primary path or secondary path will
+     * get updated, also redundant EEPROM(if any) path with new keyword's value.
+     *
+     * In case of hardware path, only given hardware path gets updated with new
+     * keyword’s value, any backup or redundant EEPROM (if exists) paths won't
+     * get updated.
+     *
+     * @param[in] i_vpdPath - DBus object path or EEPROM path.
+     * @param[in] i_recordName - Record name.
+     * @param[in] i_keywordName - Keyword name.
+     * @param[in] i_keywordValue - Keyword value.
+     * @param[in] i_onHardware - True if i_vpdPath is EEPROM path, false
+     * otherwise.
+     *
+     * @return On success returns 0, otherwise returns -1.
+     */
+    int writeKeyword(std::string i_vpdPath, const std::string& i_recordName,
+                     const std::string& i_keywordName,
+                     const std::string& i_keywordValue,
+                     const bool i_onHardware) noexcept;
+
+    /**
+     * @brief Reset specific keywords on System VPD to default value.
+     *
+     * This API resets specific System VPD keywords to default value. The
+     * keyword values are reset on:
+     * 1. Primary EEPROM path.
+     * 2. Secondary EEPROM path.
+     * 3. D-Bus cache.
+     * 4. Backup path.
+     *
+     * @return On success returns 0, otherwise returns -1.
+     */
+    int cleanSystemVpd() const noexcept;
+
+    /**
+     * @brief Dump all the inventory objects in JSON or table format to console.
+     *
+     * This API dumps specific properties of all the inventory objects to
+     * console in JSON or table format to console. The inventory object paths
+     * are extracted from PIM. For each object, the following properties are
+     * dumped to console:
+     * - Present property, Pretty Name, Location Code, Sub Model
+     * - SN, PN, CC, FN, DR keywords under VINI record.
+     * If the "Present" property of a FRU is false, the FRU is not dumped to
+     * console.
+     * FRUs whose object path end in "unit([0-9][0-9]?)" are also not dumped to
+     * console.
+     *
+     * @param[in] i_dumpTable - Flag which specifies if the inventory should be
+     * dumped in table format or not.
+     *
+     * @return On success returns 0, otherwise returns -1.
+     */
+    int dumpInventory(bool i_dumpTable = false) const noexcept;
+};
+} // namespace vpd
diff --git a/vpd-tool/meson.build b/vpd-tool/meson.build
new file mode 100644
index 0000000..a2c1ea1
--- /dev/null
+++ b/vpd-tool/meson.build
@@ -0,0 +1,19 @@
+compiler = meson.get_compiler('cpp')
+if compiler.has_header('CLI/CLI.hpp')
+    CLI11_dep = declare_dependency()
+else
+    CLI11_dep = dependency('CLI11')
+endif
+
+sdbusplus = dependency('sdbusplus', fallback: [ 'sdbusplus', 'sdbusplus_dep' ])
+dependency_list = [CLI11_dep, sdbusplus]
+
+sources = ['src/vpd_tool_main.cpp',
+            'src/vpd_tool.cpp']
+
+vpd_tool_exe = executable('vpd-tool',
+                          sources,
+                          include_directories : ['../', 'include/'],
+                          dependencies: dependency_list,
+                          install: true
+                        )
\ No newline at end of file
diff --git a/vpd-tool/src/vpd_tool.cpp b/vpd-tool/src/vpd_tool.cpp
new file mode 100644
index 0000000..f6e4cd9
--- /dev/null
+++ b/vpd-tool/src/vpd_tool.cpp
@@ -0,0 +1,1195 @@
+#include "config.h"
+
+#include "vpd_tool.hpp"
+
+#include "tool_constants.hpp"
+#include "tool_types.hpp"
+#include "tool_utils.hpp"
+
+#include <iostream>
+#include <regex>
+#include <tuple>
+namespace vpd
+{
+int VpdTool::readKeyword(
+    const std::string& i_vpdPath, const std::string& i_recordName,
+    const std::string& i_keywordName, const bool i_onHardware,
+    const std::string& i_fileToSave)
+{
+    int l_rc = constants::FAILURE;
+    try
+    {
+        types::DbusVariantType l_keywordValue;
+        if (i_onHardware)
+        {
+            l_keywordValue = utils::readKeywordFromHardware(
+                i_vpdPath, std::make_tuple(i_recordName, i_keywordName));
+        }
+        else
+        {
+            std::string l_inventoryObjectPath(
+                constants::baseInventoryPath + i_vpdPath);
+
+            l_keywordValue = utils::readDbusProperty(
+                constants::inventoryManagerService, l_inventoryObjectPath,
+                constants::ipzVpdInfPrefix + i_recordName, i_keywordName);
+        }
+
+        if (const auto l_value =
+                std::get_if<types::BinaryVector>(&l_keywordValue);
+            l_value && !l_value->empty())
+        {
+            // ToDo: Print value in both ASCII and hex formats
+            const std::string& l_keywordStrValue =
+                utils::getPrintableValue(*l_value);
+
+            if (i_fileToSave.empty())
+            {
+                utils::displayOnConsole(i_vpdPath, i_keywordName,
+                                        l_keywordStrValue);
+                l_rc = constants::SUCCESS;
+            }
+            else
+            {
+                if (utils::saveToFile(i_fileToSave, l_keywordStrValue))
+                {
+                    std::cout
+                        << "Value read is saved on the file: " << i_fileToSave
+                        << std::endl;
+                    l_rc = constants::SUCCESS;
+                }
+                else
+                {
+                    std::cerr
+                        << "Error while saving the read value on the file: "
+                        << i_fileToSave
+                        << "\nDisplaying the read value on console"
+                        << std::endl;
+                    utils::displayOnConsole(i_vpdPath, i_keywordName,
+                                            l_keywordStrValue);
+                }
+            }
+        }
+        else
+        {
+            // TODO: Enable logging when verbose is enabled.
+            // std::cout << "Invalid data type or empty data received." <<
+            // std::endl;
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        /*std::cerr << "Read keyword's value for path: " << i_vpdPath
+                  << ", Record: " << i_recordName
+                  << ", Keyword: " << i_keywordName
+                  << " is failed, exception: " << l_ex.what() << std::endl;*/
+    }
+    return l_rc;
+}
+
+int VpdTool::dumpObject(std::string i_fruPath) const noexcept
+{
+    int l_rc{constants::FAILURE};
+    try
+    {
+        // ToDo: For PFuture system take only full path from the user.
+        i_fruPath = constants::baseInventoryPath + i_fruPath;
+
+        nlohmann::json l_resultJsonArray = nlohmann::json::array({});
+        const nlohmann::json l_fruJson = getFruProperties(i_fruPath);
+        if (!l_fruJson.empty())
+        {
+            l_resultJsonArray += l_fruJson;
+
+            utils::printJson(l_resultJsonArray);
+        }
+        else
+        {
+            std::cout << "FRU [" << i_fruPath
+                      << "] is not present in the system" << std::endl;
+        }
+        l_rc = constants::SUCCESS;
+    }
+    catch (std::exception& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        // std::cerr << "Dump Object failed for FRU [" << i_fruPath
+        //           << "], Error: " << l_ex.what() << std::endl;
+    }
+    return l_rc;
+}
+
+nlohmann::json VpdTool::getFruProperties(const std::string& i_objectPath) const
+{
+    // check if FRU is present in the system
+    if (!isFruPresent(i_objectPath))
+    {
+        return nlohmann::json::object_t();
+    }
+
+    nlohmann::json l_fruJson = nlohmann::json::object_t({});
+
+    l_fruJson.emplace(i_objectPath, nlohmann::json::object_t({}));
+
+    auto& l_fruObject = l_fruJson[i_objectPath];
+
+    const auto l_prettyNameInJson = getInventoryPropertyJson<std::string>(
+        i_objectPath, constants::inventoryItemInf, "PrettyName");
+    if (!l_prettyNameInJson.empty())
+    {
+        l_fruObject.insert(l_prettyNameInJson.cbegin(),
+                           l_prettyNameInJson.cend());
+    }
+
+    const auto l_locationCodeInJson = getInventoryPropertyJson<std::string>(
+        i_objectPath, constants::locationCodeInf, "LocationCode");
+    if (!l_locationCodeInJson.empty())
+    {
+        l_fruObject.insert(l_locationCodeInJson.cbegin(),
+                           l_locationCodeInJson.cend());
+    }
+
+    const auto l_subModelInJson = getInventoryPropertyJson<std::string>(
+        i_objectPath, constants::assetInf, "SubModel");
+
+    if (!l_subModelInJson.empty() &&
+        !l_subModelInJson.value("SubModel", "").empty())
+    {
+        l_fruObject.insert(l_subModelInJson.cbegin(), l_subModelInJson.cend());
+    }
+
+    // Get the properties under VINI interface.
+
+    nlohmann::json l_viniPropertiesInJson = nlohmann::json::object({});
+
+    auto l_readViniKeyWord = [i_objectPath, &l_viniPropertiesInJson,
+                              this](const std::string& i_keyWord) {
+        const nlohmann::json l_keyWordJson =
+            getInventoryPropertyJson<vpd::types::BinaryVector>(
+                i_objectPath, constants::kwdVpdInf, i_keyWord);
+        l_viniPropertiesInJson.insert(l_keyWordJson.cbegin(),
+                                      l_keyWordJson.cend());
+    };
+
+    const std::vector<std::string> l_viniKeywords = {"SN", "PN", "CC", "FN",
+                                                     "DR"};
+
+    std::for_each(l_viniKeywords.cbegin(), l_viniKeywords.cend(),
+                  l_readViniKeyWord);
+
+    if (!l_viniPropertiesInJson.empty())
+    {
+        l_fruObject.insert(l_viniPropertiesInJson.cbegin(),
+                           l_viniPropertiesInJson.cend());
+    }
+
+    const auto l_typePropertyJson = getFruTypeProperty(i_objectPath);
+    if (!l_typePropertyJson.empty())
+    {
+        l_fruObject.insert(l_typePropertyJson.cbegin(),
+                           l_typePropertyJson.cend());
+    }
+
+    return l_fruJson;
+}
+
+template <typename PropertyType>
+nlohmann::json VpdTool::getInventoryPropertyJson(
+    const std::string& i_objectPath, const std::string& i_interface,
+    const std::string& i_propertyName) const noexcept
+{
+    nlohmann::json l_resultInJson = nlohmann::json::object({});
+    try
+    {
+        types::DbusVariantType l_keyWordValue;
+
+        l_keyWordValue =
+            utils::readDbusProperty(constants::inventoryManagerService,
+                                    i_objectPath, i_interface, i_propertyName);
+
+        if (const auto l_value = std::get_if<PropertyType>(&l_keyWordValue))
+        {
+            if constexpr (std::is_same<PropertyType, std::string>::value)
+            {
+                l_resultInJson.emplace(i_propertyName, *l_value);
+            }
+            else if constexpr (std::is_same<PropertyType, bool>::value)
+            {
+                l_resultInJson.emplace(i_propertyName,
+                                       *l_value ? "true" : "false");
+            }
+            else if constexpr (std::is_same<PropertyType,
+                                            types::BinaryVector>::value)
+            {
+                const std::string& l_keywordStrValue =
+                    vpd::utils::getPrintableValue(*l_value);
+
+                l_resultInJson.emplace(i_propertyName, l_keywordStrValue);
+            }
+        }
+        else
+        {
+            // TODO: Enable logging when verbose is enabled.
+            // std::cout << "Invalid data type received." << std::endl;
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        /*std::cerr << "Read " << i_propertyName << " value for FRU path: " <<
+           i_objectPath
+                  << ", failed with exception: " << l_ex.what() << std::endl;*/
+    }
+    return l_resultInJson;
+}
+
+int VpdTool::fixSystemVpd() const noexcept
+{
+    int l_rc = constants::FAILURE;
+
+    nlohmann::json l_backupRestoreCfgJsonObj = getBackupRestoreCfgJsonObj();
+    if (!fetchKeywordInfo(l_backupRestoreCfgJsonObj))
+    {
+        return l_rc;
+    }
+
+    printSystemVpd(l_backupRestoreCfgJsonObj);
+
+    do
+    {
+        printFixSystemVpdOption(types::UserOption::UseBackupDataForAll);
+        printFixSystemVpdOption(
+            types::UserOption::UseSystemBackplaneDataForAll);
+        printFixSystemVpdOption(types::UserOption::MoreOptions);
+        printFixSystemVpdOption(types::UserOption::Exit);
+
+        int l_userSelectedOption = types::UserOption::Exit;
+        std::cin >> l_userSelectedOption;
+
+        std::cout << std::endl << std::string(191, '=') << std::endl;
+
+        if (types::UserOption::UseBackupDataForAll == l_userSelectedOption)
+        {
+            l_rc = updateAllKeywords(l_backupRestoreCfgJsonObj, true);
+            break;
+        }
+        else if (types::UserOption::UseSystemBackplaneDataForAll ==
+                 l_userSelectedOption)
+        {
+            l_rc = updateAllKeywords(l_backupRestoreCfgJsonObj, false);
+            break;
+        }
+        else if (types::UserOption::MoreOptions == l_userSelectedOption)
+        {
+            l_rc = handleMoreOption(l_backupRestoreCfgJsonObj);
+            break;
+        }
+        else if (types::UserOption::Exit == l_userSelectedOption)
+        {
+            std::cout << "Exit successfully" << std::endl;
+            break;
+        }
+        else
+        {
+            std::cout << "Provide a valid option. Retry." << std::endl;
+        }
+    } while (true);
+
+    return l_rc;
+}
+
+int VpdTool::writeKeyword(
+    std::string i_vpdPath, const std::string& i_recordName,
+    const std::string& i_keywordName, const std::string& i_keywordValue,
+    const bool i_onHardware) noexcept
+{
+    int l_rc = constants::FAILURE;
+    try
+    {
+        if (i_vpdPath.empty() || i_recordName.empty() ||
+            i_keywordName.empty() || i_keywordValue.empty())
+        {
+            throw std::runtime_error("Received input is empty.");
+        }
+
+        auto l_paramsToWrite =
+            std::make_tuple(i_recordName, i_keywordName,
+                            utils::convertToBinary(i_keywordValue));
+
+        if (i_onHardware)
+        {
+            l_rc = utils::writeKeywordOnHardware(i_vpdPath, l_paramsToWrite);
+        }
+        else
+        {
+            i_vpdPath = constants::baseInventoryPath + i_vpdPath;
+            l_rc = utils::writeKeyword(i_vpdPath, l_paramsToWrite);
+        }
+
+        if (l_rc > 0)
+        {
+            std::cout << "Data updated successfully " << std::endl;
+            l_rc = constants::SUCCESS;
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        // TODO: Enable log when verbose is enabled.
+        std::cerr << "Write keyword's value for path: " << i_vpdPath
+                  << ", Record: " << i_recordName
+                  << ", Keyword: " << i_keywordName
+                  << " is failed. Exception: " << l_ex.what() << std::endl;
+    }
+    return l_rc;
+}
+
+nlohmann::json VpdTool::getBackupRestoreCfgJsonObj() const noexcept
+{
+    nlohmann::json l_parsedBackupRestoreJson{};
+    try
+    {
+        nlohmann::json l_parsedSystemJson =
+            utils::getParsedJson(INVENTORY_JSON_SYM_LINK);
+
+        // check for mandatory fields at this point itself.
+        if (!l_parsedSystemJson.contains("backupRestoreConfigPath"))
+        {
+            throw std::runtime_error(
+                "backupRestoreConfigPath tag is missing from system config JSON : " +
+                std::string(INVENTORY_JSON_SYM_LINK));
+        }
+
+        l_parsedBackupRestoreJson =
+            utils::getParsedJson(l_parsedSystemJson["backupRestoreConfigPath"]);
+    }
+    catch (const std::exception& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        std::cerr << l_ex.what() << std::endl;
+    }
+
+    return l_parsedBackupRestoreJson;
+}
+
+int VpdTool::cleanSystemVpd() const noexcept
+{
+    try
+    {
+        // get the keyword map from backup_restore json
+        // iterate through the keyword map get default value of
+        // l_keywordName.
+        // use writeKeyword API to update default value on hardware,
+        // backup and D - Bus.
+        const nlohmann::json l_parsedBackupRestoreJson =
+            getBackupRestoreCfgJsonObj();
+
+        // check for mandatory tags
+        if (l_parsedBackupRestoreJson.contains("source") &&
+            l_parsedBackupRestoreJson.contains("backupMap") &&
+            l_parsedBackupRestoreJson["source"].contains("hardwarePath") &&
+            l_parsedBackupRestoreJson["backupMap"].is_array())
+        {
+            // get the source hardware path
+            const auto& l_hardwarePath =
+                l_parsedBackupRestoreJson["source"]["hardwarePath"];
+
+            // iterate through the backup map
+            for (const auto& l_aRecordKwInfo :
+                 l_parsedBackupRestoreJson["backupMap"])
+            {
+                // check if Manufacturing Reset is required for this entry
+                const bool l_isMfgCleanRequired =
+                    l_aRecordKwInfo.value("isManufactureResetRequired", false);
+
+                if (l_isMfgCleanRequired)
+                {
+                    // get the Record name and Keyword name
+                    const std::string& l_srcRecordName =
+                        l_aRecordKwInfo.value("sourceRecord", "");
+                    const std::string& l_srcKeywordName =
+                        l_aRecordKwInfo.value("sourceKeyword", "");
+
+                    // validate the Record name, Keyword name and the
+                    // defaultValue
+                    if (!l_srcRecordName.empty() && !l_srcKeywordName.empty() &&
+                        l_aRecordKwInfo.contains("defaultValue") &&
+                        l_aRecordKwInfo["defaultValue"].is_array())
+                    {
+                        const types::BinaryVector l_defaultBinaryValue =
+                            l_aRecordKwInfo["defaultValue"]
+                                .get<types::BinaryVector>();
+
+                        // update the Keyword with default value, use D-Bus
+                        // method UpdateKeyword exposed by vpd-manager.
+                        // Note: writing to all paths (Primary EEPROM path,
+                        // Secondary EEPROM path, D-Bus cache and Backup path)
+                        // is the responsibility of vpd-manager's UpdateKeyword
+                        // API
+                        if (constants::FAILURE ==
+                            utils::writeKeyword(
+                                l_hardwarePath,
+                                std::make_tuple(l_srcRecordName,
+                                                l_srcKeywordName,
+                                                l_defaultBinaryValue)))
+                        {
+                            // TODO: Enable logging when verbose
+                            // is enabled.
+                            std::cerr << "Failed to update " << l_srcRecordName
+                                      << ":" << l_srcKeywordName << std::endl;
+                        }
+                    }
+                    else
+                    {
+                        std::cerr
+                            << "Unrecognized Entry Record [" << l_srcRecordName
+                            << "] Keyword [" << l_srcKeywordName
+                            << "] in Backup Restore JSON backup map"
+                            << std::endl;
+                    }
+                } // mfgClean required check
+            } // keyword list loop
+        }
+        else // backupRestoreJson is not valid
+        {
+            std::cerr << "Backup Restore JSON is not valid" << std::endl;
+        }
+
+        // success/failure message
+        std::cout << "The critical keywords from system backplane VPD has "
+                     "been reset successfully."
+                  << std::endl;
+
+    } // try block end
+    catch (const std::exception& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        std::cerr
+            << "Manufacturing reset on system vpd keywords is unsuccessful. Error : "
+            << l_ex.what() << std::endl;
+    }
+    return constants::SUCCESS;
+}
+
+bool VpdTool::fetchKeywordInfo(nlohmann::json& io_parsedJsonObj) const noexcept
+{
+    bool l_returnValue = false;
+    try
+    {
+        if (io_parsedJsonObj.empty() || !io_parsedJsonObj.contains("source") ||
+            !io_parsedJsonObj.contains("destination") ||
+            !io_parsedJsonObj.contains("backupMap"))
+        {
+            throw std::runtime_error("Invalid JSON");
+        }
+
+        std::string l_srcVpdPath;
+        std::string l_dstVpdPath;
+
+        bool l_isSourceOnHardware = false;
+        if (l_srcVpdPath = io_parsedJsonObj["source"].value("hardwarePath", "");
+            !l_srcVpdPath.empty())
+        {
+            l_isSourceOnHardware = true;
+        }
+        else if (l_srcVpdPath =
+                     io_parsedJsonObj["source"].value("inventoryPath", "");
+                 l_srcVpdPath.empty())
+        {
+            throw std::runtime_error("Source path is empty in JSON");
+        }
+
+        bool l_isDestinationOnHardware = false;
+        if (l_dstVpdPath =
+                io_parsedJsonObj["destination"].value("hardwarePath", "");
+            !l_dstVpdPath.empty())
+        {
+            l_isDestinationOnHardware = true;
+        }
+        else if (l_dstVpdPath =
+                     io_parsedJsonObj["destination"].value("inventoryPath", "");
+                 l_dstVpdPath.empty())
+        {
+            throw std::runtime_error("Destination path is empty in JSON");
+        }
+
+        for (auto& l_aRecordKwInfo : io_parsedJsonObj["backupMap"])
+        {
+            const std::string& l_srcRecordName =
+                l_aRecordKwInfo.value("sourceRecord", "");
+            const std::string& l_srcKeywordName =
+                l_aRecordKwInfo.value("sourceKeyword", "");
+            const std::string& l_dstRecordName =
+                l_aRecordKwInfo.value("destinationRecord", "");
+            const std::string& l_dstKeywordName =
+                l_aRecordKwInfo.value("destinationKeyword", "");
+
+            if (l_srcRecordName.empty() || l_dstRecordName.empty() ||
+                l_srcKeywordName.empty() || l_dstKeywordName.empty())
+            {
+                // TODO: Enable logging when verbose is enabled.
+                std::cout << "Record or keyword not found in the JSON."
+                          << std::endl;
+                continue;
+            }
+
+            types::DbusVariantType l_srcKeywordVariant;
+            if (l_isSourceOnHardware)
+            {
+                l_srcKeywordVariant = utils::readKeywordFromHardware(
+                    l_srcVpdPath,
+                    std::make_tuple(l_srcRecordName, l_srcKeywordName));
+            }
+            else
+            {
+                l_srcKeywordVariant = utils::readDbusProperty(
+                    constants::inventoryManagerService, l_srcVpdPath,
+                    constants::ipzVpdInfPrefix + l_srcRecordName,
+                    l_srcKeywordName);
+            }
+
+            if (auto l_srcKeywordValue =
+                    std::get_if<types::BinaryVector>(&l_srcKeywordVariant);
+                l_srcKeywordValue && !l_srcKeywordValue->empty())
+            {
+                l_aRecordKwInfo["sourcekeywordValue"] = *l_srcKeywordValue;
+            }
+            else
+            {
+                // TODO: Enable logging when verbose is enabled.
+                std::cout
+                    << "Invalid data type or empty data received, for source record: "
+                    << l_srcRecordName << ", keyword: " << l_srcKeywordName
+                    << std::endl;
+                continue;
+            }
+
+            types::DbusVariantType l_dstKeywordVariant;
+            if (l_isDestinationOnHardware)
+            {
+                l_dstKeywordVariant = utils::readKeywordFromHardware(
+                    l_dstVpdPath,
+                    std::make_tuple(l_dstRecordName, l_dstKeywordName));
+            }
+            else
+            {
+                l_dstKeywordVariant = utils::readDbusProperty(
+                    constants::inventoryManagerService, l_dstVpdPath,
+                    constants::ipzVpdInfPrefix + l_dstRecordName,
+                    l_dstKeywordName);
+            }
+
+            if (auto l_dstKeywordValue =
+                    std::get_if<types::BinaryVector>(&l_dstKeywordVariant);
+                l_dstKeywordValue && !l_dstKeywordValue->empty())
+            {
+                l_aRecordKwInfo["destinationkeywordValue"] = *l_dstKeywordValue;
+            }
+            else
+            {
+                // TODO: Enable logging when verbose is enabled.
+                std::cout
+                    << "Invalid data type or empty data received, for destination record: "
+                    << l_dstRecordName << ", keyword: " << l_dstKeywordName
+                    << std::endl;
+                continue;
+            }
+        }
+
+        l_returnValue = true;
+    }
+    catch (const std::exception& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        std::cerr << l_ex.what() << std::endl;
+    }
+
+    return l_returnValue;
+}
+
+nlohmann::json
+    VpdTool::getFruTypeProperty(const std::string& i_objectPath) const noexcept
+{
+    nlohmann::json l_resultInJson = nlohmann::json::object({});
+    std::vector<std::string> l_pimInfList;
+
+    auto l_serviceInfMap = utils::GetServiceInterfacesForObject(
+        i_objectPath, std::vector<std::string>{constants::inventoryItemInf});
+    if (l_serviceInfMap.contains(constants::inventoryManagerService))
+    {
+        l_pimInfList = l_serviceInfMap[constants::inventoryManagerService];
+
+        // iterate through the list and find
+        // "xyz.openbmc_project.Inventory.Item.*"
+        for (const auto& l_interface : l_pimInfList)
+        {
+            if (l_interface.find(constants::inventoryItemInf) !=
+                    std::string::npos &&
+                l_interface.length() >
+                    std::string(constants::inventoryItemInf).length())
+            {
+                l_resultInJson.emplace("type", l_interface);
+            }
+        }
+    }
+    return l_resultInJson;
+}
+
+bool VpdTool::isFruPresent(const std::string& i_objectPath) const noexcept
+{
+    bool l_returnValue{false};
+    try
+    {
+        types::DbusVariantType l_keyWordValue;
+
+        l_keyWordValue = utils::readDbusProperty(
+            constants::inventoryManagerService, i_objectPath,
+            constants::inventoryItemInf, "Present");
+
+        if (const auto l_value = std::get_if<bool>(&l_keyWordValue))
+        {
+            l_returnValue = *l_value;
+        }
+    }
+    catch (const std::runtime_error& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        // std::cerr << "Failed to check \"Present\" property for FRU "
+        //           << i_objectPath << " Error: " << l_ex.what() <<
+        //           std::endl;
+    }
+    return l_returnValue;
+}
+
+void VpdTool::printFixSystemVpdOption(
+    const types::UserOption& i_option) const noexcept
+{
+    switch (i_option)
+    {
+        case types::UserOption::Exit:
+            std::cout << "Enter 0 => To exit successfully : ";
+            break;
+        case types::UserOption::UseBackupDataForAll:
+            std::cout << "Enter 1 => If you choose the data on backup for all "
+                         "mismatching record-keyword pairs"
+                      << std::endl;
+            break;
+        case types::UserOption::UseSystemBackplaneDataForAll:
+            std::cout << "Enter 2 => If you choose the data on primary for all "
+                         "mismatching record-keyword pairs"
+                      << std::endl;
+            break;
+        case types::UserOption::MoreOptions:
+            std::cout << "Enter 3 => If you wish to explore more options"
+                      << std::endl;
+            break;
+        case types::UserOption::UseBackupDataForCurrent:
+            std::cout << "Enter 4 => If you choose the data on backup as the "
+                         "right value"
+                      << std::endl;
+            break;
+        case types::UserOption::UseSystemBackplaneDataForCurrent:
+            std::cout << "Enter 5 => If you choose the data on primary as the "
+                         "right value"
+                      << std::endl;
+            break;
+        case types::UserOption::NewValueOnBoth:
+            std::cout
+                << "Enter 6 => If you wish to enter a new value to update "
+                   "both on backup and primary"
+                << std::endl;
+            break;
+        case types::UserOption::SkipCurrent:
+            std::cout << "Enter 7 => If you wish to skip the above "
+                         "record-keyword pair"
+                      << std::endl;
+            break;
+    }
+}
+
+int VpdTool::dumpInventory(bool i_dumpTable) const noexcept
+{
+    int l_rc{constants::FAILURE};
+
+    try
+    {
+        // get all object paths under PIM
+        const auto l_objectPaths = utils::GetSubTreePaths(
+            constants::baseInventoryPath, 0,
+            std::vector<std::string>{constants::inventoryItemInf});
+
+        if (!l_objectPaths.empty())
+        {
+            nlohmann::json l_resultInJson = nlohmann::json::array({});
+
+            std::for_each(l_objectPaths.begin(), l_objectPaths.end(),
+                          [&](const auto& l_objectPath) {
+                              const auto l_fruJson =
+                                  getFruProperties(l_objectPath);
+                              if (!l_fruJson.empty())
+                              {
+                                  if (l_resultInJson.empty())
+                                  {
+                                      l_resultInJson += l_fruJson;
+                                  }
+                                  else
+                                  {
+                                      l_resultInJson.at(0).insert(
+                                          l_fruJson.cbegin(), l_fruJson.cend());
+                                  }
+                              }
+                          });
+
+            if (i_dumpTable)
+            {
+                // create Table object
+                utils::Table l_inventoryTable{};
+
+                // columns to be populated in the Inventory table
+                const std::vector<types::TableColumnNameSizePair>
+                    l_tableColumns = {
+                        {"FRU", 100},         {"CC", 6},  {"DR", 20},
+                        {"LocationCode", 32}, {"PN", 8},  {"PrettyName", 80},
+                        {"SubModel", 10},     {"SN", 15}, {"type", 60}};
+
+                types::TableInputData l_tableData;
+
+                // First prepare the Table Columns
+                for (const auto& l_column : l_tableColumns)
+                {
+                    if (constants::FAILURE ==
+                        l_inventoryTable.AddColumn(l_column.first,
+                                                   l_column.second))
+                    {
+                        // TODO: Enable logging when verbose is enabled.
+                        std::cerr << "Failed to add column " << l_column.first
+                                  << " in Inventory Table." << std::endl;
+                    }
+                }
+
+                // iterate through the json array
+                for (const auto& l_fruEntry : l_resultInJson[0].items())
+                {
+                    // if object path ends in "unit([0-9][0-9]?)", skip adding
+                    // the object path in the table
+                    if (std::regex_search(l_fruEntry.key(),
+                                          std::regex("unit([0-9][0-9]?)")))
+                    {
+                        continue;
+                    }
+
+                    std::vector<std::string> l_row;
+                    for (const auto& l_column : l_tableColumns)
+                    {
+                        const auto& l_fruJson = l_fruEntry.value();
+
+                        if (l_column.first == "FRU")
+                        {
+                            l_row.push_back(l_fruEntry.key());
+                        }
+                        else
+                        {
+                            if (l_fruJson.contains(l_column.first))
+                            {
+                                l_row.push_back(l_fruJson[l_column.first]);
+                            }
+                            else
+                            {
+                                l_row.push_back("");
+                            }
+                        }
+                    }
+
+                    l_tableData.push_back(l_row);
+                }
+
+                l_rc = l_inventoryTable.Print(l_tableData);
+            }
+            else
+            {
+                // print JSON to console
+                utils::printJson(l_resultInJson);
+                l_rc = constants::SUCCESS;
+            }
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        std::cerr << "Dump inventory failed. Error: " << l_ex.what()
+                  << std::endl;
+    }
+    return l_rc;
+}
+
+void VpdTool::printSystemVpd(
+    const nlohmann::json& i_parsedJsonObj) const noexcept
+{
+    if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("backupMap"))
+    {
+        // TODO: Enable logging when verbose is enabled.
+        std::cerr << "Invalid JSON to print system VPD" << std::endl;
+    }
+
+    std::string l_outline(191, '=');
+    std::cout << "\nRestorable record-keyword pairs and their data on backup & "
+                 "primary.\n\n"
+              << l_outline << std::endl;
+
+    std::cout << std::left << std::setw(6) << "S.No" << std::left
+              << std::setw(8) << "Record" << std::left << std::setw(9)
+              << "Keyword" << std::left << std::setw(75) << "Data On Backup"
+              << std::left << std::setw(75) << "Data On Primary" << std::left
+              << std::setw(14) << "Data Mismatch\n"
+              << l_outline << std::endl;
+
+    uint8_t l_slNum = 0;
+
+    for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
+    {
+        if (l_aRecordKwInfo.contains("sourceRecord") ||
+            l_aRecordKwInfo.contains("sourceKeyword") ||
+            l_aRecordKwInfo.contains("destinationkeywordValue") ||
+            l_aRecordKwInfo.contains("sourcekeywordValue"))
+        {
+            std::string l_mismatchFound{
+                (l_aRecordKwInfo["destinationkeywordValue"] !=
+                 l_aRecordKwInfo["sourcekeywordValue"])
+                    ? "YES"
+                    : "NO"};
+
+            std::string l_splitLine(191, '-');
+
+            try
+            {
+                std::cout << std::left << std::setw(6)
+                          << static_cast<int>(++l_slNum) << std::left
+                          << std::setw(8)
+                          << l_aRecordKwInfo.value("sourceRecord", "")
+                          << std::left << std::setw(9)
+                          << l_aRecordKwInfo.value("sourceKeyword", "")
+                          << std::left << std::setw(75) << std::setfill(' ')
+                          << utils::getPrintableValue(
+                                 l_aRecordKwInfo["destinationkeywordValue"])
+                          << std::left << std::setw(75) << std::setfill(' ')
+                          << utils::getPrintableValue(
+                                 l_aRecordKwInfo["sourcekeywordValue"])
+                          << std::left << std::setw(14) << l_mismatchFound
+                          << '\n'
+                          << l_splitLine << std::endl;
+            }
+            catch (const std::exception& l_ex)
+            {
+                // TODO: Enable logging when verbose is enabled.
+                std::cerr << l_ex.what() << std::endl;
+            }
+        }
+    }
+}
+
+int VpdTool::updateAllKeywords(const nlohmann::json& i_parsedJsonObj,
+                               bool i_useBackupData) const noexcept
+{
+    int l_rc = constants::FAILURE;
+
+    if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("source") ||
+        !i_parsedJsonObj.contains("backupMap"))
+    {
+        // TODO: Enable logging when verbose is enabled.
+        std::cerr << "Invalid JSON" << std::endl;
+        return l_rc;
+    }
+
+    std::string l_srcVpdPath;
+    if (auto l_vpdPath = i_parsedJsonObj["source"].value("hardwarePath", "");
+        !l_vpdPath.empty())
+    {
+        l_srcVpdPath = l_vpdPath;
+    }
+    else if (auto l_vpdPath =
+                 i_parsedJsonObj["source"].value("inventoryPath", "");
+             !l_vpdPath.empty())
+    {
+        l_srcVpdPath = l_vpdPath;
+    }
+    else
+    {
+        // TODO: Enable logging when verbose is enabled.
+        std::cerr << "source path information is missing in JSON" << std::endl;
+        return l_rc;
+    }
+
+    bool l_anyMismatchFound = false;
+    for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
+    {
+        if (!l_aRecordKwInfo.contains("sourceRecord") ||
+            !l_aRecordKwInfo.contains("sourceKeyword") ||
+            !l_aRecordKwInfo.contains("destinationkeywordValue") ||
+            !l_aRecordKwInfo.contains("sourcekeywordValue"))
+        {
+            // TODO: Enable logging when verbose is enabled.
+            std::cerr << "Missing required information in the JSON"
+                      << std::endl;
+            continue;
+        }
+
+        if (l_aRecordKwInfo["sourcekeywordValue"] !=
+            l_aRecordKwInfo["destinationkeywordValue"])
+        {
+            l_anyMismatchFound = true;
+
+            auto l_keywordValue =
+                i_useBackupData ? l_aRecordKwInfo["destinationkeywordValue"]
+                                : l_aRecordKwInfo["sourcekeywordValue"];
+
+            auto l_paramsToWrite = std::make_tuple(
+                l_aRecordKwInfo["sourceRecord"],
+                l_aRecordKwInfo["sourceKeyword"], l_keywordValue);
+
+            try
+            {
+                l_rc = utils::writeKeyword(l_srcVpdPath, l_paramsToWrite);
+                if (l_rc > 0)
+                {
+                    l_rc = constants::SUCCESS;
+                }
+            }
+            catch (const std::exception& l_ex)
+            {
+                // TODO: Enable logging when verbose is enabled.
+                std::cerr << "write keyword failed for record: "
+                          << l_aRecordKwInfo["sourceRecord"]
+                          << ", keyword: " << l_aRecordKwInfo["sourceKeyword"]
+                          << ", error: " << l_ex.what() << std::ends;
+            }
+        }
+    }
+
+    std::string l_dataUsed =
+        (i_useBackupData ? "data from backup" : "data from primary VPD");
+    if (l_anyMismatchFound)
+    {
+        std::cout << "Data updated successfully for all mismatching "
+                     "record-keyword pairs by choosing their corresponding "
+                  << l_dataUsed << ". Exit successfully." << std::endl;
+    }
+    else
+    {
+        std::cout << "No mismatch found for any of the above mentioned "
+                     "record-keyword pair. Exit successfully."
+                  << std::endl;
+    }
+
+    return l_rc;
+}
+
+int VpdTool::handleMoreOption(
+    const nlohmann::json& i_parsedJsonObj) const noexcept
+{
+    int l_rc = constants::FAILURE;
+
+    try
+    {
+        if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("backupMap"))
+        {
+            throw std::runtime_error("Invalid JSON");
+        }
+
+        std::string l_srcVpdPath;
+
+        if (auto l_vpdPath =
+                i_parsedJsonObj["source"].value("hardwarePath", "");
+            !l_vpdPath.empty())
+        {
+            l_srcVpdPath = l_vpdPath;
+        }
+        else if (auto l_vpdPath =
+                     i_parsedJsonObj["source"].value("inventoryPath", "");
+                 !l_vpdPath.empty())
+        {
+            l_srcVpdPath = l_vpdPath;
+        }
+        else
+        {
+            throw std::runtime_error(
+                "source path information is missing in JSON");
+        }
+
+        auto updateKeywordValue =
+            [](std::string io_vpdPath, const std::string& i_recordName,
+               const std::string& i_keywordName,
+               const types::BinaryVector& i_keywordValue) -> int {
+            int l_rc = constants::FAILURE;
+
+            try
+            {
+                auto l_paramsToWrite = std::make_tuple(
+                    i_recordName, i_keywordName, i_keywordValue);
+                l_rc = utils::writeKeyword(io_vpdPath, l_paramsToWrite);
+
+                if (l_rc > 0)
+                {
+                    std::cout << std::endl
+                              << "Data updated successfully." << std::endl;
+                }
+            }
+            catch (const std::exception& l_ex)
+            {
+                // TODO: Enable log when verbose is enabled.
+                std::cerr << l_ex.what() << std::endl;
+            }
+            return l_rc;
+        };
+
+        do
+        {
+            int l_slNum = 0;
+            bool l_exit = false;
+
+            for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
+            {
+                if (!l_aRecordKwInfo.contains("sourceRecord") ||
+                    !l_aRecordKwInfo.contains("sourceKeyword") ||
+                    !l_aRecordKwInfo.contains("destinationkeywordValue") ||
+                    !l_aRecordKwInfo.contains("sourcekeywordValue"))
+                {
+                    // TODO: Enable logging when verbose is enabled.
+                    std::cerr
+                        << "Source or destination information is missing in the JSON."
+                        << std::endl;
+                    continue;
+                }
+
+                const std::string l_mismatchFound{
+                    (l_aRecordKwInfo["sourcekeywordValue"] !=
+                     l_aRecordKwInfo["destinationkeywordValue"])
+                        ? "YES"
+                        : "NO"};
+
+                std::cout << std::endl
+                          << std::left << std::setw(6) << "S.No" << std::left
+                          << std::setw(8) << "Record" << std::left
+                          << std::setw(9) << "Keyword" << std::left
+                          << std::setw(75) << std::setfill(' ') << "Backup Data"
+                          << std::left << std::setw(75) << std::setfill(' ')
+                          << "Primary Data" << std::left << std::setw(14)
+                          << "Data Mismatch" << std::endl;
+
+                std::cout << std::left << std::setw(6)
+                          << static_cast<int>(++l_slNum) << std::left
+                          << std::setw(8)
+                          << l_aRecordKwInfo.value("sourceRecord", "")
+                          << std::left << std::setw(9)
+                          << l_aRecordKwInfo.value("sourceKeyword", "")
+                          << std::left << std::setw(75) << std::setfill(' ')
+                          << utils::getPrintableValue(
+                                 l_aRecordKwInfo["destinationkeywordValue"])
+                          << std::left << std::setw(75) << std::setfill(' ')
+                          << utils::getPrintableValue(
+                                 l_aRecordKwInfo["sourcekeywordValue"])
+                          << std::left << std::setw(14) << l_mismatchFound
+                          << std::endl;
+
+                std::cout << std::string(191, '=') << std::endl;
+
+                if (constants::STR_CMP_SUCCESS ==
+                    l_mismatchFound.compare("YES"))
+                {
+                    printFixSystemVpdOption(
+                        types::UserOption::UseBackupDataForCurrent);
+                    printFixSystemVpdOption(
+                        types::UserOption::UseSystemBackplaneDataForCurrent);
+                    printFixSystemVpdOption(types::UserOption::NewValueOnBoth);
+                    printFixSystemVpdOption(types::UserOption::SkipCurrent);
+                    printFixSystemVpdOption(types::UserOption::Exit);
+                }
+                else
+                {
+                    std::cout << "No mismatch found." << std::endl << std::endl;
+                    printFixSystemVpdOption(types::UserOption::NewValueOnBoth);
+                    printFixSystemVpdOption(types::UserOption::SkipCurrent);
+                    printFixSystemVpdOption(types::UserOption::Exit);
+                }
+
+                int l_userSelectedOption = types::UserOption::Exit;
+                std::cin >> l_userSelectedOption;
+
+                if (types::UserOption::UseBackupDataForCurrent ==
+                    l_userSelectedOption)
+                {
+                    l_rc = updateKeywordValue(
+                        l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
+                        l_aRecordKwInfo["sourceKeyword"],
+                        l_aRecordKwInfo["destinationkeywordValue"]);
+                }
+                else if (types::UserOption::UseSystemBackplaneDataForCurrent ==
+                         l_userSelectedOption)
+                {
+                    l_rc = updateKeywordValue(
+                        l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
+                        l_aRecordKwInfo["sourceKeyword"],
+                        l_aRecordKwInfo["sourcekeywordValue"]);
+                }
+                else if (types::UserOption::NewValueOnBoth ==
+                         l_userSelectedOption)
+                {
+                    std::string l_newValue;
+                    std::cout
+                        << std::endl
+                        << "Enter the new value to update on both "
+                           "primary & backup. Value should be in ASCII or "
+                           "in HEX(prefixed with 0x) : ";
+                    std::cin >> l_newValue;
+                    std::cout << std::endl
+                              << std::string(191, '=') << std::endl;
+
+                    try
+                    {
+                        l_rc = updateKeywordValue(
+                            l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
+                            l_aRecordKwInfo["sourceKeyword"],
+                            utils::convertToBinary(l_newValue));
+                    }
+                    catch (const std::exception& l_ex)
+                    {
+                        // TODO: Enable logging when verbose is enabled.
+                        std::cerr << l_ex.what() << std::endl;
+                    }
+                }
+                else if (types::UserOption::SkipCurrent == l_userSelectedOption)
+                {
+                    std::cout << std::endl
+                              << "Skipped the above record-keyword pair. "
+                                 "Continue to the next available pair."
+                              << std::endl;
+                }
+                else if (types::UserOption::Exit == l_userSelectedOption)
+                {
+                    std::cout << "Exit successfully" << std::endl;
+                    l_exit = true;
+                    break;
+                }
+                else
+                {
+                    std::cout << "Provide a valid option. Retrying for the "
+                                 "current record-keyword pair"
+                              << std::endl;
+                }
+            }
+            if (l_exit)
+            {
+                l_rc = constants::SUCCESS;
+                break;
+            }
+        } while (true);
+    }
+    catch (const std::exception& l_ex)
+    {
+        // TODO: Enable logging when verbose is enabled.
+        std::cerr << l_ex.what() << std::endl;
+    }
+
+    return l_rc;
+}
+
+} // namespace vpd
diff --git a/vpd-tool/src/vpd_tool_main.cpp b/vpd-tool/src/vpd_tool_main.cpp
new file mode 100644
index 0000000..3fdf5d1
--- /dev/null
+++ b/vpd-tool/src/vpd_tool_main.cpp
@@ -0,0 +1,335 @@
+#include "tool_constants.hpp"
+#include "vpd_tool.hpp"
+
+#include <CLI/CLI.hpp>
+
+#include <filesystem>
+#include <iostream>
+
+/**
+ * @brief API to perform manufacturing clean.
+ *
+ * @param[in] i_mfgCleanConfirmFlag - Confirmation flag to perform manufacturing
+ * clean.
+ *
+ * @return Status returned by cleanSystemVpd operation, success otherwise.
+ */
+int doMfgClean(const auto& i_mfgCleanConfirmFlag)
+{
+    if (i_mfgCleanConfirmFlag->empty())
+    {
+        constexpr auto MAX_CONFIRMATION_STR_LENGTH{3};
+        std::string l_confirmation{};
+        std::cout
+            << "This option resets some of the system VPD keywords to their default values. Do you really wish to proceed further?[yes/no]:";
+        std::cin >> std::setw(MAX_CONFIRMATION_STR_LENGTH) >> l_confirmation;
+
+        if (l_confirmation != "yes")
+        {
+            return vpd::constants::SUCCESS;
+        }
+    }
+
+    vpd::VpdTool l_vpdToolObj;
+    return l_vpdToolObj.cleanSystemVpd();
+}
+
+/**
+ * @brief API to write keyword's value.
+ *
+ * @param[in] i_hardwareFlag - Flag to perform write on hardware.
+ * @param[in] i_keywordValueOption - Option to read keyword value from command.
+ * @param[in] i_vpdPath - DBus object path or EEPROM path.
+ * @param[in] i_recordName - Record to be updated.
+ * @param[in] i_keywordName - Keyword to be updated.
+ * @param[in] i_keywordValue - Value to be updated in keyword.
+ *
+ * @return Status of writeKeyword operation, failure otherwise.
+ */
+int writeKeyword(const auto& i_hardwareFlag, const auto& i_keywordValueOption,
+                 const std::string& i_vpdPath, const std::string& i_recordName,
+                 const std::string& i_keywordName,
+                 const std::string& i_keywordValue)
+{
+    std::error_code l_ec;
+
+    if (!i_hardwareFlag->empty() && !std::filesystem::exists(i_vpdPath, l_ec))
+    {
+        std::cerr << "Given EEPROM file path doesn't exist : " + i_vpdPath
+                  << std::endl;
+        return vpd::constants::FAILURE;
+    }
+
+    if (l_ec)
+    {
+        std::cerr << "filesystem call exists failed for file: " << i_vpdPath
+                  << ", reason: " + l_ec.message() << std::endl;
+        return vpd::constants::FAILURE;
+    }
+
+    if (!i_keywordValueOption->empty() && i_keywordValue.empty())
+    {
+        std::cerr
+            << "Please provide keyword value.\nUse --value/--file to give "
+               "keyword value. Refer --help."
+            << std::endl;
+        return vpd::constants::FAILURE;
+    }
+
+    if (i_keywordValueOption->empty())
+    {
+        std::cerr
+            << "Please provide keyword value.\nUse --value/--file to give "
+               "keyword value. Refer --help."
+            << std::endl;
+        return vpd::constants::FAILURE;
+    }
+
+    vpd::VpdTool l_vpdToolObj;
+    return l_vpdToolObj.writeKeyword(i_vpdPath, i_recordName, i_keywordName,
+                                     i_keywordValue, !i_hardwareFlag->empty());
+}
+
+/**
+ * @brief API to read keyword's value.
+ *
+ * @param[in] i_hardwareFlag - Flag to perform write on hardware.
+ * @param[in] i_vpdPath - DBus object path or EEPROM path.
+ * @param[in] i_recordName - Record to be updated.
+ * @param[in] i_keywordName - Keyword to be updated.
+ * @param[in] i_filePath - File path to save keyword's read value.
+ *
+ * @return Status of readKeyword operation, failure otherwise.
+ */
+int readKeyword(const auto& i_hardwareFlag, const std::string& i_vpdPath,
+                const std::string& i_recordName,
+                const std::string& i_keywordName, const std::string& i_filePath)
+{
+    std::error_code l_ec;
+
+    if (!i_hardwareFlag->empty() && !std::filesystem::exists(i_vpdPath, l_ec))
+    {
+        std::string l_errMessage{
+            "Given EEPROM file path doesn't exist : " + i_vpdPath};
+
+        if (l_ec)
+        {
+            l_errMessage += ". filesystem call exists failed, reason: " +
+                            l_ec.message();
+        }
+
+        std::cerr << l_errMessage << std::endl;
+        return vpd::constants::FAILURE;
+    }
+
+    bool l_isHardwareOperation = (!i_hardwareFlag->empty() ? true : false);
+
+    vpd::VpdTool l_vpdToolObj;
+    return l_vpdToolObj.readKeyword(i_vpdPath, i_recordName, i_keywordName,
+                                    l_isHardwareOperation, i_filePath);
+}
+
+/**
+ * @brief API to check option value pair in the tool command.
+ *
+ * In VPD tool command, some of the option(s) mandate values to be passed along
+ * with the option. This API based on option, detects those mandatory value(s).
+ *
+ * @param[in] i_objectOption - Option to pass object path.
+ * @param[in] i_vpdPath - Object path, DBus or EEPROM.
+ * @param[in] i_recordOption - Option to pass record name.
+ * @param[in] i_recordName - Record name.
+ * @param[in] i_keywordOption - Option to pass keyword name.
+ * @param[in] i_keywordName - Keyword name.
+ *
+ * @return Success if corresponding value is found against option, failure
+ * otherwise.
+ */
+int checkOptionValuePair(const auto& i_objectOption, const auto& i_vpdPath,
+                         const auto& i_recordOption, const auto& i_recordName,
+                         const auto& i_keywordOption, const auto& i_keywordName)
+{
+    if (!i_objectOption->empty() && i_vpdPath.empty())
+    {
+        std::cout << "Given path is empty." << std::endl;
+        return vpd::constants::FAILURE;
+    }
+
+    if (!i_recordOption->empty() &&
+        (i_recordName.size() != vpd::constants::RECORD_SIZE))
+    {
+        std::cerr << "Record " << i_recordName << " is not supported."
+                  << std::endl;
+        return vpd::constants::FAILURE;
+    }
+
+    if (!i_keywordOption->empty() &&
+        (i_keywordName.size() != vpd::constants::KEYWORD_SIZE))
+    {
+        std::cerr << "Keyword " << i_keywordName << " is not supported."
+                  << std::endl;
+        return vpd::constants::FAILURE;
+    }
+
+    return vpd::constants::SUCCESS;
+}
+
+/**
+ * @brief API to create app footer.
+ *
+ * @param[in] i_app - CLI::App object.
+ */
+void updateFooter(CLI::App& i_app)
+{
+    i_app.footer(
+        "Read:\n"
+        "    IPZ Format:\n"
+        "        From DBus to console: "
+        "vpd-tool -r -O <DBus Object Path> -R <Record Name> -K <Keyword Name>\n"
+        "        From DBus to file: "
+        "vpd-tool -r -O <DBus Object Path> -R <Record Name> -K <Keyword Name> --file <File Path>\n"
+        "        From hardware to console: "
+        "vpd-tool -r -H -O <EEPROM Path> -R <Record Name> -K <Keyword Name>\n"
+        "        From hardware to file: "
+        "vpd-tool -r -H -O <EEPROM Path> -R <Record Name> -K <Keyword Name> --file <File Path>\n"
+        "Write:\n"
+        "    IPZ Format:\n"
+        "        On DBus: "
+        "vpd-tool -w/-u -O <DBus Object Path> -R <Record Name> -K <Keyword Name> -V <Keyword Value>\n"
+        "        On DBus, take keyword value from file:\n"
+        "              vpd-tool -w/-u -O <DBus Object Path> -R <Record Name> -K <Keyword Name> --file <File Path>\n"
+        "        On hardware: "
+        "vpd-tool -w/-u -H -O <EEPROM Path> -R <Record Name> -K <Keyword Name> -V <Keyword Value>\n"
+        "        On hardware, take keyword value from file:\n"
+        "              vpd-tool -w/-u -H -O <EEPROM Path> -R <Record Name> -K <Keyword Name> --file <File Path>\n"
+        "Dump Object:\n"
+        "    From DBus to console: "
+        "vpd-tool -o -O <DBus Object Path>\n"
+        "Fix System VPD:\n"
+        "    vpd-tool --fixSystemVPD\n"
+        "MfgClean:\n"
+        "        Flag to clean and reset specific keywords on system VPD to its default value.\n"
+        "        vpd-tool --mfgClean\n"
+        "Dump Inventory:\n"
+        "   From DBus to console in JSON format: "
+        "vpd-tool -i\n"
+        "   From DBus to console in Table format: "
+        "vpd-tool -i -t\n");
+}
+
+int main(int argc, char** argv)
+{
+    CLI::App l_app{"VPD Command Line Tool"};
+
+    std::string l_vpdPath{};
+    std::string l_recordName{};
+    std::string l_keywordName{};
+    std::string l_filePath{};
+    std::string l_keywordValue{};
+
+    updateFooter(l_app);
+
+    auto l_objectOption =
+        l_app.add_option("--object, -O", l_vpdPath, "File path");
+    auto l_recordOption =
+        l_app.add_option("--record, -R", l_recordName, "Record name");
+    auto l_keywordOption =
+        l_app.add_option("--keyword, -K", l_keywordName, "Keyword name");
+
+    // Enable when file option is implemented.
+    /*auto l_fileOption = l_app.add_option("--file", l_filePath,
+                                         "Absolute file path");*/
+
+    auto l_keywordValueOption =
+        l_app.add_option("--value, -V", l_keywordValue,
+                         "Keyword value in ascii/hex format."
+                         " ascii ex: 01234; hex ex: 0x30313233");
+
+    auto l_hardwareFlag =
+        l_app.add_flag("--Hardware, -H", "CAUTION: Developer only option.");
+
+    auto l_readFlag = l_app.add_flag("--readKeyword, -r", "Read keyword")
+                          ->needs(l_objectOption)
+                          ->needs(l_recordOption)
+                          ->needs(l_keywordOption);
+
+    auto l_writeFlag =
+        l_app
+            .add_flag(
+                "--writeKeyword, -w,--updateKeyword, -u",
+                "Write keyword, Note: Irrespective of DBus or hardware path provided, primary and backup, redundant EEPROM(if any) paths will get updated with given key value")
+            ->needs(l_objectOption)
+            ->needs(l_recordOption)
+            ->needs(l_keywordOption);
+
+    // ToDo: Take offset value from user for hardware path.
+
+    auto l_dumpObjFlag =
+        l_app
+            .add_flag("--dumpObject, -o",
+                      "Dump specific properties of an inventory object")
+            ->needs(l_objectOption);
+
+    auto l_fixSystemVpdFlag = l_app.add_flag(
+        "--fixSystemVPD",
+        "Use this option to interactively fix critical system VPD keywords");
+    auto l_dumpInventoryFlag =
+        l_app.add_flag("--dumpInventory, -i", "Dump all the inventory objects");
+
+    auto l_mfgCleanFlag = l_app.add_flag(
+        "--mfgClean", "Manufacturing clean on system VPD keyword");
+
+    auto l_mfgCleanConfirmFlag = l_app.add_flag(
+        "--yes", "Using this flag with --mfgClean option, assumes "
+                 "yes to proceed without confirmation.");
+
+    auto l_dumpInventoryTableFlag =
+        l_app.add_flag("--table, -t", "Dump inventory in table format");
+
+    CLI11_PARSE(l_app, argc, argv);
+
+    if (checkOptionValuePair(l_objectOption, l_vpdPath, l_recordOption,
+                             l_recordName, l_keywordOption, l_keywordName) ==
+        vpd::constants::FAILURE)
+    {
+        return vpd::constants::FAILURE;
+    }
+
+    if (!l_readFlag->empty())
+    {
+        return readKeyword(l_hardwareFlag, l_vpdPath, l_recordName,
+                           l_keywordName, l_filePath);
+    }
+
+    if (!l_writeFlag->empty())
+    {
+        return writeKeyword(l_hardwareFlag, l_keywordValueOption, l_vpdPath,
+                            l_recordName, l_keywordName, l_keywordValue);
+    }
+
+    if (!l_dumpObjFlag->empty())
+    {
+        vpd::VpdTool l_vpdToolObj;
+        return l_vpdToolObj.dumpObject(l_vpdPath);
+    }
+
+    if (!l_fixSystemVpdFlag->empty())
+    {
+        vpd::VpdTool l_vpdToolObj;
+        return l_vpdToolObj.fixSystemVpd();
+    }
+
+    if (!l_mfgCleanFlag->empty())
+    {
+        return doMfgClean(l_mfgCleanConfirmFlag);
+    }
+
+    if (!l_dumpInventoryFlag->empty())
+    {
+        vpd::VpdTool l_vpdToolObj;
+        return l_vpdToolObj.dumpInventory(!l_dumpInventoryTableFlag->empty());
+    }
+
+    std::cout << l_app.help() << std::endl;
+    return vpd::constants::FAILURE;
+}
