diff --git a/control/json/triggers/signal.cpp b/control/json/triggers/signal.cpp
new file mode 100644
index 0000000..b5e1e6a
--- /dev/null
+++ b/control/json/triggers/signal.cpp
@@ -0,0 +1,154 @@
+/**
+ * Copyright © 2021 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "signal.hpp"
+
+#include "../manager.hpp"
+#include "action.hpp"
+#include "group.hpp"
+#include "handlers.hpp"
+
+#include <fmt/format.h>
+
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <numeric>
+#include <utility>
+#include <vector>
+
+namespace phosphor::fan::control::json::trigger::signal
+{
+
+using json = nlohmann::json;
+using namespace phosphor::logging;
+using namespace sdbusplus::bus::match;
+
+void subscribe(const std::string& match, SignalPkg&& signalPkg,
+               std::function<bool(SignalPkg&)> isSameSig, Manager* mgr)
+{
+    // TODO - Handle signal subscriptions to objects hosted by fan control
+    auto& signalData = mgr->getSignal(match);
+    if (signalData.empty())
+    {
+        // Signal subscription doesnt exist, add signal package and subscribe
+        std::vector<SignalPkg> pkgs = {signalPkg};
+        std::unique_ptr<std::vector<SignalPkg>> dataPkgs =
+            std::make_unique<std::vector<SignalPkg>>(std::move(pkgs));
+        std::unique_ptr<sdbusplus::server::match::match> ptrMatch = nullptr;
+        if (!match.empty())
+        {
+            // Subscribe to signal
+            ptrMatch = std::make_unique<sdbusplus::server::match::match>(
+                mgr->getBus(), match.c_str(),
+                std::bind(std::mem_fn(&Manager::handleSignal), &(*mgr),
+                          std::placeholders::_1, dataPkgs.get()));
+        }
+        signalData.emplace_back(std::move(dataPkgs), std::move(ptrMatch));
+    }
+    else
+    {
+        // Signal subscription already exists
+        // Only a single signal data entry tied to each match is supported
+        auto& pkgs = std::get<std::unique_ptr<std::vector<SignalPkg>>>(
+            signalData.front());
+        for (auto& pkg : *pkgs)
+        {
+            if (isSameSig(pkg))
+            {
+                // Same signal expected, add action to be run when signal
+                // received
+                auto& pkgActions = std::get<SignalActions>(signalPkg);
+                auto& actions = std::get<SignalActions>(pkg);
+                // Only one action is given on the signal package passed in
+                actions.push_back(pkgActions.front());
+            }
+            else
+            {
+                // Expected signal differs, add signal package
+                (*pkgs).emplace_back(std::move(signalPkg));
+            }
+        }
+    }
+}
+
+void propertiesChanged(Manager* mgr, const std::string& eventName,
+                       std::unique_ptr<ActionBase>& action)
+{
+    // Groups are optional, but a signal triggered event with no groups
+    // will do nothing since signals require a group
+    for (const auto& group : action->getGroups())
+    {
+        for (const auto& member : group.getMembers())
+        {
+            // Setup property changed signal handler on the group member's
+            // property
+            const auto match =
+                rules::propertiesChanged(member, group.getInterface());
+            SignalPkg signalPkg = {Handlers::propertiesChanged,
+                                   SignalObject(std::cref(member),
+                                                std::cref(group.getInterface()),
+                                                std::cref(group.getProperty())),
+                                   SignalActions({action})};
+            auto isSameSig = [&prop = group.getProperty()](SignalPkg& pkg) {
+                auto& obj = std::get<SignalObject>(pkg);
+                return prop == std::get<Prop>(obj);
+            };
+
+            subscribe(match, std::move(signalPkg), isSameSig, mgr);
+        }
+    }
+}
+
+void triggerSignal(const json& jsonObj, const std::string& eventName,
+                   Manager* mgr,
+                   std::vector<std::unique_ptr<ActionBase>>& actions)
+{
+    auto subscriber = signals.end();
+    if (jsonObj.contains("signal"))
+    {
+        auto signal = jsonObj["signal"].get<std::string>();
+        std::transform(signal.begin(), signal.end(), signal.begin(), tolower);
+        subscriber = signals.find(signal);
+    }
+    if (subscriber == signals.end())
+    {
+        // Construct list of available signals
+        auto availSignals =
+            std::accumulate(std::next(signals.begin()), signals.end(),
+                            signals.begin()->first, [](auto list, auto signal) {
+                                return std::move(list) + ", " + signal.first;
+                            });
+        auto msg =
+            fmt::format("Event '{}' requires a supported signal given to be "
+                        "triggered by signal, available signals: {}",
+                        eventName, availSignals);
+        log<level::ERR>(msg.c_str());
+        throw std::runtime_error(msg.c_str());
+    }
+
+    for (auto& action : actions)
+    {
+        // Call signal subscriber for each group in the action
+        subscriber->second(mgr, eventName, action);
+    }
+}
+
+} // namespace phosphor::fan::control::json::trigger::signal
