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
