diff --git a/vpd-manager/gpioMonitor.cpp b/vpd-manager/gpioMonitor.cpp
new file mode 100644
index 0000000..b57d52c
--- /dev/null
+++ b/vpd-manager/gpioMonitor.cpp
@@ -0,0 +1,173 @@
+#include "gpioMonitor.hpp"
+
+#include "common_utility.hpp"
+#include "ibm_vpd_utils.hpp"
+
+#include <systemd/sd-event.h>
+
+#include <chrono>
+#include <gpiod.hpp>
+#include <sdeventplus/clock.hpp>
+#include <sdeventplus/utility/timer.hpp>
+
+using namespace std;
+using namespace openpower::vpd::constants;
+using sdeventplus::ClockId;
+using sdeventplus::Event;
+using Timer = sdeventplus::utility::Timer<ClockId::Monotonic>;
+using namespace std::chrono_literals;
+
+namespace openpower
+{
+namespace vpd
+{
+namespace manager
+{
+
+bool GpioEventHandler::getPresencePinValue()
+{
+    Byte gpioData = 1;
+    gpiod::line presenceLine = gpiod::find_line(presencePin);
+    if (!presenceLine)
+    {
+        cerr << "Error getPresencePinValue: couldn't find presence line:"
+             << presencePin << " on GPIO \n";
+        // return previous state as we couldn't read current state
+        return prevPresPinValue;
+    }
+
+    presenceLine.request(
+        {"Op-panel presence line", gpiod::line_request::DIRECTION_INPUT, 0});
+
+    gpioData = presenceLine.get_value();
+
+    return gpioData;
+}
+
+void GpioMonitor::initGpioInfos(Event& event)
+{
+    Byte outputValue = 0;
+    Byte presenceValue = 0;
+    string presencePinName{}, outputPinName{};
+    string devNameAddr{}, driverType{}, busType{}, objectPath{};
+
+    for (const auto& eachFRU : jsonFile["frus"].items())
+    {
+        for (const auto& eachInventory : eachFRU.value())
+        {
+            objectPath = eachInventory["inventoryPath"];
+
+            if ((eachInventory.find("presence") != eachInventory.end()) &&
+                (eachInventory.find("preAction") != eachInventory.end()))
+            {
+                for (const auto& presStatus : eachInventory["presence"].items())
+                {
+                    if (presStatus.key() == "pin")
+                    {
+                        presencePinName = presStatus.value();
+                    }
+                    else if (presStatus.key() == "value")
+                    {
+                        presenceValue = presStatus.value();
+                    }
+                }
+
+                // Based on presence pin value, preAction pin will be set/reset
+                // This action will be taken before vpd collection.
+                for (const auto& preAction : eachInventory["preAction"].items())
+                {
+                    if (preAction.key() == "pin")
+                    {
+                        outputPinName = preAction.value();
+                    }
+                    else if (preAction.key() == "value")
+                    {
+                        outputValue = preAction.value();
+                    }
+                }
+
+                devNameAddr = eachInventory["devAddress"];
+                driverType = eachInventory["driverType"];
+                busType = eachInventory["busType"];
+
+                // Init all Gpio info variables
+                std::shared_ptr<GpioEventHandler> gpioObj =
+                    make_shared<GpioEventHandler>(
+                        presencePinName, presenceValue, outputPinName,
+                        outputValue, devNameAddr, driverType, busType,
+                        objectPath, event);
+
+                gpioObjects.push_back(gpioObj);
+            }
+        }
+    }
+}
+
+void GpioEventHandler::toggleGpio()
+{
+    bool presPinVal = getPresencePinValue();
+    bool isPresent = false;
+
+    // preserve the new value
+    prevPresPinValue = presPinVal;
+
+    if (presPinVal == presenceValue)
+    {
+        isPresent = true;
+    }
+
+    // if FRU went away set the present property to false
+    if (!isPresent)
+    {
+        inventory::ObjectMap objects;
+        inventory::InterfaceMap interfaces;
+        inventory::PropertyMap presProp;
+
+        presProp.emplace("Present", false);
+        interfaces.emplace("xyz.openbmc_project.Inventory.Item", presProp);
+        objects.emplace(objectPath, move(interfaces));
+
+        common::utility::callPIM(move(objects));
+    }
+
+    gpiod::line outputLine = gpiod::find_line(outputPin);
+    if (!outputLine)
+    {
+        cerr << "Error: toggleGpio: couldn't find output line:" << outputPin
+             << ". Skipping update\n";
+
+        return;
+    }
+
+    outputLine.request({"FRU presence: update the output GPIO pin",
+                        gpiod::line_request::DIRECTION_OUTPUT, 0},
+                       isPresent ? outputValue : (!outputValue));
+
+    string cmnd = createBindUnbindDriverCmnd(devNameAddr, busType, driverType,
+                                             isPresent ? "bind" : "unbind");
+
+    cout << cmnd << endl;
+    executeCmd(cmnd);
+}
+
+void GpioEventHandler::doEventAndTimerSetup(sdeventplus::Event& event)
+{
+    prevPresPinValue = getPresencePinValue();
+
+    static vector<shared_ptr<Timer>> timers;
+    shared_ptr<Timer> timer = make_shared<Timer>(
+        event,
+        [this](Timer&) {
+            if (hasEventOccurred())
+            {
+                toggleGpio();
+            }
+        },
+        std::chrono::seconds{5s});
+
+    timers.push_back(timer);
+}
+
+} // namespace manager
+} // namespace vpd
+} // namespace openpower
\ No newline at end of file
