diff --git a/Redfish.md b/Redfish.md
index 3770aab..e8a22fa 100644
--- a/Redfish.md
+++ b/Redfish.md
@@ -986,6 +986,7 @@
 #### Processor
 
 - InstructionSet
+- LocationIndicatorActive
 - Manufacturer
 - MaxSpeedMHz
 - PartNumber
diff --git a/redfish-core/lib/processor.hpp b/redfish-core/lib/processor.hpp
index d4afd3d..9f41b8d 100644
--- a/redfish-core/lib/processor.hpp
+++ b/redfish-core/lib/processor.hpp
@@ -7,11 +7,13 @@
 
 #include "app.hpp"
 #include "async_resp.hpp"
+#include "dbus_singleton.hpp"
 #include "dbus_utility.hpp"
 #include "error_messages.hpp"
 #include "generated/enums/processor.hpp"
 #include "generated/enums/resource.hpp"
 #include "http_request.hpp"
+#include "led.hpp"
 #include "logging.hpp"
 #include "query.hpp"
 #include "registries/privilege_registry.hpp"
@@ -728,20 +730,66 @@
         });
 }
 
+inline void handleProcessorSubtree(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& processorId,
+    const std::function<
+        void(const std::string& objectPath,
+             const dbus::utility::MapperServiceMap& serviceMap)>& callback,
+    const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreeResponse& subtree)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
+        messages::internalError(asyncResp->res);
+        return;
+    }
+    for (const auto& [objectPath, serviceMap] : subtree)
+    {
+        // Ignore any objects which don't end with our desired cpu name
+        sdbusplus::message::object_path path(objectPath);
+        if (path.filename() == processorId)
+        {
+            // Filter out objects that don't have the CPU-specific
+            // interfaces to make sure we can return 404 on non-CPUs
+            // (e.g. /redfish/../Processors/dimm0)
+            for (const auto& [serviceName, interfaceList] : serviceMap)
+            {
+                if (std::ranges::find_first_of(interfaceList,
+                                               processorInterfaces) !=
+                    interfaceList.end())
+                {
+                    // Process the first object which matches cpu name and
+                    // required interfaces, and potentially ignore any other
+                    // matching objects. Assume all interfaces we want to
+                    // process must be on the same object path.
+
+                    callback(objectPath, serviceMap);
+                    return;
+                }
+            }
+        }
+    }
+    messages::resourceNotFound(asyncResp->res, "Processor", processorId);
+}
+
 /**
  * Find the D-Bus object representing the requested Processor, and call the
  * handler with the results. If matching object is not found, add 404 error to
  * response and don't call the handler.
  *
- * @param[in,out]   resp            Async HTTP response.
+ * @param[in,out]   asyncResp       Async HTTP response.
  * @param[in]       processorId     Redfish Processor Id.
- * @param[in]       handler         Callback to continue processing request upon
+ * @param[in]       callback        Callback to continue processing request upon
  *                                  successfully finding object.
  */
-template <typename Handler>
-inline void getProcessorObject(const std::shared_ptr<bmcweb::AsyncResp>& resp,
-                               const std::string& processorId,
-                               Handler&& handler)
+inline void getProcessorObject(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& processorId,
+    std::function<void(const std::string& objectPath,
+                       const dbus::utility::MapperServiceMap& serviceMap)>&&
+        callback)
 {
     BMCWEB_LOG_DEBUG("Get available system processor resources.");
 
@@ -758,52 +806,11 @@
         "xyz.openbmc_project.Control.Power.Throttle"};
     dbus::utility::getSubTree(
         "/xyz/openbmc_project/inventory", 0, interfaces,
-        [resp, processorId, handler = std::forward<Handler>(handler)](
+        [asyncResp, processorId, callback{std::move(callback)}](
             const boost::system::error_code& ec,
             const dbus::utility::MapperGetSubTreeResponse& subtree) {
-            if (ec)
-            {
-                BMCWEB_LOG_DEBUG("DBUS response error: {}", ec);
-                messages::internalError(resp->res);
-                return;
-            }
-            for (const auto& [objectPath, serviceMap] : subtree)
-            {
-                // Ignore any objects which don't end with our desired cpu name
-                if (!objectPath.ends_with(processorId))
-                {
-                    continue;
-                }
-
-                bool found = false;
-                // Filter out objects that don't have the CPU-specific
-                // interfaces to make sure we can return 404 on non-CPUs
-                // (e.g. /redfish/../Processors/dimm0)
-                for (const auto& [serviceName, interfaceList] : serviceMap)
-                {
-                    if (std::ranges::find_first_of(interfaceList,
-                                                   processorInterfaces) !=
-                        std::end(interfaceList))
-                    {
-                        found = true;
-                        break;
-                    }
-                }
-
-                if (!found)
-                {
-                    continue;
-                }
-
-                // Process the first object which does match our cpu name and
-                // required interfaces, and potentially ignore any other
-                // matching objects. Assume all interfaces we want to process
-                // must be on the same object path.
-
-                handler(objectPath, serviceMap);
-                return;
-            }
-            messages::resourceNotFound(resp->res, "Processor", processorId);
+            handleProcessorSubtree(asyncResp, processorId, callback, ec,
+                                   subtree);
         });
 }
 
@@ -812,6 +819,14 @@
     const std::string& processorId, const std::string& objectPath,
     const dbus::utility::MapperServiceMap& serviceMap)
 {
+    asyncResp->res.addHeader(
+        boost::beast::http::field::link,
+        "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
+    asyncResp->res.jsonValue["@odata.type"] = "#Processor.v1_18_0.Processor";
+    asyncResp->res.jsonValue["@odata.id"] =
+        boost::urls::format("/redfish/v1/Systems/{}/Processors/{}",
+                            BMCWEB_REDFISH_SYSTEM_URI_NAME, processorId);
+
     for (const auto& [serviceName, interfaceList] : serviceMap)
     {
         for (const auto& interface : interfaceList)
@@ -861,6 +876,10 @@
             {
                 getThrottleProperties(asyncResp, serviceName, objectPath);
             }
+            else if (interface == "xyz.openbmc_project.Association.Definitions")
+            {
+                getLocationIndicatorActive(asyncResp, objectPath);
+            }
         }
     }
 }
@@ -1063,6 +1082,97 @@
         "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
 }
 
+inline void handleProcessorGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName, const std::string& processorId)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+    {
+        // Option currently returns no systems.  TBD
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+    if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    getProcessorObject(
+        asyncResp, processorId,
+        std::bind_front(getProcessorData, asyncResp, processorId));
+}
+
+inline void doPatchProcessor(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& processorId,
+    const std::optional<std::string>& appliedConfigUri,
+    std::optional<bool> locationIndicatorActive, const std::string& objectPath,
+    const dbus::utility::MapperServiceMap& serviceMap)
+{
+    if (appliedConfigUri)
+    {
+        patchAppliedOperatingConfig(asyncResp, processorId, *appliedConfigUri,
+                                    objectPath, serviceMap);
+    }
+
+    if (locationIndicatorActive)
+    {
+        // Utility function handles reporting errors
+        setLocationIndicatorActive(asyncResp, objectPath,
+                                   *locationIndicatorActive);
+    }
+}
+
+inline void handleProcessorPatch(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName, const std::string& processorId)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+    {
+        // Option currently returns no systems.  TBD
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+    if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    std::optional<std::string> appliedConfigUri;
+    std::optional<bool> locationIndicatorActive;
+    if (!json_util::readJsonPatch(
+            req, asyncResp->res,                                  //
+            "AppliedOperatingConfig/@odata.id", appliedConfigUri, //
+            "LocationIndicatorActive", locationIndicatorActive    //
+            ))
+    {
+        return;
+    }
+
+    // Check for 404 and find matching D-Bus object, then run
+    // property patch handlers if that all succeeds.
+    getProcessorObject(
+        asyncResp, processorId,
+        std::bind_front(doPatchProcessor, asyncResp, processorId,
+                        appliedConfigUri, locationIndicatorActive));
+}
+
 inline void requestRoutesOperatingConfigCollection(App& app)
 {
     BMCWEB_ROUTE(app,
@@ -1295,88 +1405,13 @@
 
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
         .privileges(redfish::privileges::getProcessor)
-        .methods(
-            boost::beast::http::verb::
-                get)([&app](const crow::Request& req,
-                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                            const std::string& systemName,
-                            const std::string& processorId) {
-            if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-            {
-                return;
-            }
-            if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
-            {
-                // Option currently returns no systems.  TBD
-                messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                           systemName);
-                return;
-            }
-            if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
-            {
-                messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                           systemName);
-                return;
-            }
-
-            asyncResp->res.addHeader(
-                boost::beast::http::field::link,
-                "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
-            asyncResp->res.jsonValue["@odata.type"] =
-                "#Processor.v1_18_0.Processor";
-            asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
-                "/redfish/v1/Systems/{}/Processors/{}",
-                BMCWEB_REDFISH_SYSTEM_URI_NAME, processorId);
-
-            getProcessorObject(
-                asyncResp, processorId,
-                std::bind_front(getProcessorData, asyncResp, processorId));
-        });
+        .methods(boost::beast::http::verb::get)(
+            std::bind_front(handleProcessorGet, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
         .privileges(redfish::privileges::patchProcessor)
         .methods(boost::beast::http::verb::patch)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& systemName,
-                   const std::string& processorId) {
-                if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-                {
-                    return;
-                }
-                if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
-                {
-                    // Option currently returns no systems.  TBD
-                    messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                               systemName);
-                    return;
-                }
-                if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
-                {
-                    messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                               systemName);
-                    return;
-                }
-
-                std::optional<std::string> appliedConfigUri;
-                if (!json_util::readJsonPatch(
-                        req, asyncResp->res,                                 //
-                        "AppliedOperatingConfig/@odata.id", appliedConfigUri //
-                        ))
-                {
-                    return;
-                }
-
-                if (appliedConfigUri)
-                {
-                    // Check for 404 and find matching D-Bus object, then run
-                    // property patch handlers if that all succeeds.
-                    getProcessorObject(
-                        asyncResp, processorId,
-                        std::bind_front(patchAppliedOperatingConfig, asyncResp,
-                                        processorId, *appliedConfigUri));
-                }
-            });
+            std::bind_front(handleProcessorPatch, std::ref(app)));
 }
 
 } // namespace redfish
