diff --git a/pldm.cpp b/pldm.cpp
index c520340..22beea9 100644
--- a/pldm.cpp
+++ b/pldm.cpp
@@ -1,5 +1,7 @@
 #include "pldm.hpp"
 
+#include "file.hpp"
+
 #include <libpldm/entity.h>
 #include <libpldm/platform.h>
 #include <libpldm/state_set.h>
@@ -147,8 +149,203 @@
         if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
         {
             sensorToOCCInstance.clear();
+            occInstanceToEffecter.clear();
         }
     }
 }
 
+void Interface::fetchOCCEffecterInfo(
+    const PdrList& pdrs, OccInstanceToEffecter& instanceToEffecterMap,
+    CompositeEffecterCount& count, uint8_t& bootRestartPos)
+{
+    bool offsetFound = false;
+    auto pdr =
+        reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data());
+    auto possibleStatesPtr = pdr->possible_states;
+    for (auto offset = 0; offset < pdr->composite_effecter_count; offset++)
+    {
+        auto possibleStates =
+            reinterpret_cast<const state_effecter_possible_states*>(
+                possibleStatesPtr);
+
+        if (possibleStates->state_set_id == PLDM_STATE_SET_BOOT_RESTART_CAUSE)
+        {
+            bootRestartPos = offset;
+            effecterCount = pdr->composite_effecter_count;
+            offsetFound = true;
+            break;
+        }
+        possibleStatesPtr += sizeof(possibleStates->state_set_id) +
+                             sizeof(possibleStates->possible_states_size) +
+                             possibleStates->possible_states_size;
+    }
+
+    if (!offsetFound)
+    {
+        return;
+    }
+
+    std::map<EntityInstance, EffecterID> entityInstMap{};
+    for (auto& pdr : pdrs)
+    {
+        auto pdrPtr =
+            reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data());
+        entityInstMap.emplace(
+            static_cast<EntityInstance>(pdrPtr->entity_instance),
+            static_cast<SensorID>(pdrPtr->effecter_id));
+    }
+
+    open_power::occ::instanceID position = start;
+    for (auto const& pair : entityInstMap)
+    {
+        occInstanceToEffecter.emplace(position, pair.second);
+        position++;
+    }
+}
+
+std::vector<uint8_t>
+    Interface::prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
+                                     CompositeEffecterCount effecterCount,
+                                     uint8_t bootRestartPos)
+{
+    std::vector<uint8_t> request(
+        sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) +
+        (effecterCount * sizeof(set_effecter_state_field)));
+    auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
+    std::vector<set_effecter_state_field> stateField;
+
+    for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++)
+    {
+        if (effecterPos == bootRestartPos)
+        {
+            stateField.emplace_back(set_effecter_state_field{
+                PLDM_REQUEST_SET,
+                PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET});
+        }
+        else
+        {
+            stateField.emplace_back(
+                set_effecter_state_field{PLDM_NO_CHANGE, 0});
+        }
+    }
+    auto rc = encode_set_state_effecter_states_req(
+        instanceId, effecterId, effecterCount, stateField.data(), requestMsg);
+    if (rc != PLDM_SUCCESS)
+    {
+        log<level::ERR>("encode set effecter states request returned error ",
+                        entry("RC=%d", rc));
+        request.clear();
+    }
+    return request;
+}
+
+void Interface::resetOCC(open_power::occ::instanceID occInstanceId)
+{
+    if (!isPDREffecterCacheValid())
+    {
+        PdrList pdrs{};
+
+        try
+        {
+            auto method = bus.new_method_call(
+                "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
+                "xyz.openbmc_project.PLDM.PDR", "FindStateEffecterPDR");
+            method.append(tid, (uint16_t)PLDM_ENTITY_PROC_MODULE,
+                          (uint16_t)PLDM_STATE_SET_BOOT_RESTART_CAUSE);
+
+            auto responseMsg = bus.call(method);
+            responseMsg.read(pdrs);
+        }
+        catch (const SdBusError& e)
+        {
+            log<level::ERR>("pldm: Failed to fetch the OCC state effecter PDRs",
+                            entry("ERROR=%s", e.what()));
+        }
+
+        if (!pdrs.size())
+        {
+            log<level::ERR>("pldm: OCC state effecter PDRs not present");
+            return;
+        }
+
+        fetchOCCEffecterInfo(pdrs, occInstanceToEffecter, effecterCount,
+                             bootRestartPosition);
+    }
+
+    // Find the matching effecter for the OCC instance
+    auto effecterEntry = occInstanceToEffecter.find(occInstanceId);
+    if (effecterEntry == occInstanceToEffecter.end())
+    {
+        log<level::ERR>(
+            "pldm: Failed to find a matching effecter for OCC instance",
+            entry("OCC_INSTANCE_ID=%d", occInstanceId));
+
+        return;
+    }
+
+    uint8_t instanceId{};
+
+    try
+    {
+        auto method = bus.new_method_call(
+            "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
+            "xyz.openbmc_project.PLDM.Requester", "GetInstanceId");
+        method.append(mctpEid);
+        auto reply = bus.call(method);
+        reply.read(instanceId);
+    }
+    catch (const SdBusError& e)
+    {
+        log<level::ERR>("pldm: GetInstanceId returned error",
+                        entry("ERROR=%s", e.what()));
+        return;
+    }
+
+    // Prepare the SetStateEffecterStates request to reset the OCC
+    auto request = prepareSetEffecterReq(instanceId, effecterEntry->second,
+                                         effecterCount, bootRestartPosition);
+
+    if (request.empty())
+    {
+        log<level::ERR>("pldm: SetStateEffecterStates request message empty");
+        return;
+    }
+
+    // Connect to MCTP scoket
+    int fd = pldm_open();
+    if (fd == -1)
+    {
+        log<level::ERR>("pldm: Failed to connect to MCTP socket");
+        return;
+    }
+    open_power::occ::FileDescriptor fileFd(fd);
+
+    // Send the PLDM request message to HBRT
+    uint8_t* response = nullptr;
+    size_t responseSize{};
+    auto rc = pldm_send_recv(mctpEid, fileFd(), request.data(), request.size(),
+                             &response, &responseSize);
+    std::unique_ptr<uint8_t, decltype(std::free)*> responsePtr{response,
+                                                               std::free};
+    if (rc)
+    {
+        log<level::ERR>("pldm: pldm_send_recv failed for OCC reset",
+                        entry("RC=%d", rc));
+    }
+
+    uint8_t completionCode{};
+    auto responseMsg = reinterpret_cast<const pldm_msg*>(responsePtr.get());
+    auto rcDecode = decode_set_state_effecter_states_resp(
+        responseMsg, responseSize - sizeof(pldm_msg_hdr), &completionCode);
+    if (rcDecode || completionCode)
+    {
+        log<level::ERR>(
+            "pldm: decode_set_state_effecter_states_resp returned error",
+            entry("RC=%d", rcDecode),
+            entry("COMPLETION_CODE=%d", completionCode));
+    }
+
+    return;
+}
+
 } // namespace pldm
\ No newline at end of file
