diff --git a/ubi/Makefile.am.include b/ubi/Makefile.am.include
new file mode 100644
index 0000000..fba30d9
--- /dev/null
+++ b/ubi/Makefile.am.include
@@ -0,0 +1,2 @@
+openpower_update_manager_SOURCES += \
+	%reldir%/item_updater_ubi.cpp
diff --git a/ubi/item_updater_ubi.cpp b/ubi/item_updater_ubi.cpp
new file mode 100644
index 0000000..1c2926a
--- /dev/null
+++ b/ubi/item_updater_ubi.cpp
@@ -0,0 +1,553 @@
+#include "config.h"
+
+#include "item_updater_ubi.hpp"
+
+#include "activation.hpp"
+#include "serialize.hpp"
+#include "version.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <experimental/filesystem>
+#include <fstream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <queue>
+#include <string>
+#include <xyz/openbmc_project/Software/Version/server.hpp>
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+
+// When you see server:: you know we're referencing our base class
+namespace server = sdbusplus::xyz::openbmc_project::Software::server;
+namespace fs = std::experimental::filesystem;
+
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using namespace phosphor::logging;
+
+constexpr auto squashFSImage = "pnor.xz.squashfs";
+
+// TODO: Change paths once openbmc/openbmc#1663 is completed.
+constexpr auto MBOXD_INTERFACE = "org.openbmc.mboxd";
+constexpr auto MBOXD_PATH = "/org/openbmc/mboxd";
+
+void ItemUpdaterUbi::createActivation(sdbusplus::message::message& m)
+{
+    using SVersion = server::Version;
+    using VersionPurpose = SVersion::VersionPurpose;
+    namespace msg = sdbusplus::message;
+    namespace variant_ns = msg::variant_ns;
+
+    sdbusplus::message::object_path objPath;
+    std::map<std::string, std::map<std::string, msg::variant<std::string>>>
+        interfaces;
+    m.read(objPath, interfaces);
+
+    std::string path(std::move(objPath));
+    std::string filePath;
+    auto purpose = VersionPurpose::Unknown;
+    std::string version;
+
+    for (const auto& intf : interfaces)
+    {
+        if (intf.first == VERSION_IFACE)
+        {
+            for (const auto& property : intf.second)
+            {
+                if (property.first == "Purpose")
+                {
+                    // Only process the Host and System images
+                    auto value = SVersion::convertVersionPurposeFromString(
+                        variant_ns::get<std::string>(property.second));
+
+                    if (value == VersionPurpose::Host ||
+                        value == VersionPurpose::System)
+                    {
+                        purpose = value;
+                    }
+                }
+                else if (property.first == "Version")
+                {
+                    version = variant_ns::get<std::string>(property.second);
+                }
+            }
+        }
+        else if (intf.first == FILEPATH_IFACE)
+        {
+            for (const auto& property : intf.second)
+            {
+                if (property.first == "Path")
+                {
+                    filePath = variant_ns::get<std::string>(property.second);
+                }
+            }
+        }
+    }
+    if ((filePath.empty()) || (purpose == VersionPurpose::Unknown))
+    {
+        return;
+    }
+
+    // Version id is the last item in the path
+    auto pos = path.rfind("/");
+    if (pos == std::string::npos)
+    {
+        log<level::ERR>("No version id found in object path",
+                        entry("OBJPATH=%s", path.c_str()));
+        return;
+    }
+
+    auto versionId = path.substr(pos + 1);
+
+    if (activations.find(versionId) == activations.end())
+    {
+        // Determine the Activation state by processing the given image dir.
+        auto activationState = server::Activation::Activations::Invalid;
+        AssociationList associations = {};
+        if (validateSquashFSImage(filePath) == 0)
+        {
+            activationState = server::Activation::Activations::Ready;
+            // Create an association to the host inventory item
+            associations.emplace_back(std::make_tuple(
+                ACTIVATION_FWD_ASSOCIATION, ACTIVATION_REV_ASSOCIATION,
+                HOST_INVENTORY_PATH));
+        }
+
+        fs::path manifestPath(filePath);
+        manifestPath /= MANIFEST_FILE;
+        std::string extendedVersion =
+            (Version::getValue(
+                 manifestPath.string(),
+                 std::map<std::string, std::string>{{"extended_version", ""}}))
+                .begin()
+                ->second;
+
+        activations.insert(std::make_pair(
+            versionId, std::make_unique<Activation>(
+                           bus, path, *this, versionId, extendedVersion,
+                           activationState, associations)));
+
+        auto versionPtr = std::make_unique<Version>(
+            bus, path, *this, versionId, version, purpose, filePath,
+            std::bind(&ItemUpdaterUbi::erase, this, std::placeholders::_1));
+        versionPtr->deleteObject =
+            std::make_unique<Delete>(bus, path, *versionPtr);
+        versions.insert(std::make_pair(versionId, std::move(versionPtr)));
+    }
+    return;
+}
+
+void ItemUpdaterUbi::processPNORImage()
+{
+    // Read pnor.toc from folders under /media/
+    // to get Active Software Versions.
+    for (const auto& iter : fs::directory_iterator(MEDIA_DIR))
+    {
+        auto activationState = server::Activation::Activations::Active;
+
+        static const auto PNOR_RO_PREFIX_LEN = strlen(PNOR_RO_PREFIX);
+        static const auto PNOR_RW_PREFIX_LEN = strlen(PNOR_RW_PREFIX);
+
+        // Check if the PNOR_RO_PREFIX is the prefix of the iter.path
+        if (0 ==
+            iter.path().native().compare(0, PNOR_RO_PREFIX_LEN, PNOR_RO_PREFIX))
+        {
+            // The versionId is extracted from the path
+            // for example /media/pnor-ro-2a1022fe.
+            auto id = iter.path().native().substr(PNOR_RO_PREFIX_LEN);
+            auto pnorTOC = iter.path() / PNOR_TOC_FILE;
+            if (!fs::is_regular_file(pnorTOC))
+            {
+                log<level::ERR>("Failed to read pnorTOC.",
+                                entry("FILENAME=%s", pnorTOC.c_str()));
+                ItemUpdaterUbi::erase(id);
+                continue;
+            }
+            auto keyValues = Version::getValue(
+                pnorTOC, {{"version", ""}, {"extended_version", ""}});
+            auto& version = keyValues.at("version");
+            if (version.empty())
+            {
+                log<level::ERR>("Failed to read version from pnorTOC",
+                                entry("FILENAME=%s", pnorTOC.c_str()));
+                activationState = server::Activation::Activations::Invalid;
+            }
+
+            auto& extendedVersion = keyValues.at("extended_version");
+            if (extendedVersion.empty())
+            {
+                log<level::ERR>("Failed to read extendedVersion from pnorTOC",
+                                entry("FILENAME=%s", pnorTOC.c_str()));
+                activationState = server::Activation::Activations::Invalid;
+            }
+
+            auto purpose = server::Version::VersionPurpose::Host;
+            auto path = fs::path(SOFTWARE_OBJPATH) / id;
+            AssociationList associations = {};
+
+            if (activationState == server::Activation::Activations::Active)
+            {
+                // Create an association to the host inventory item
+                associations.emplace_back(std::make_tuple(
+                    ACTIVATION_FWD_ASSOCIATION, ACTIVATION_REV_ASSOCIATION,
+                    HOST_INVENTORY_PATH));
+
+                // Create an active association since this image is active
+                createActiveAssociation(path);
+            }
+
+            // Create Activation instance for this version.
+            activations.insert(
+                std::make_pair(id, std::make_unique<Activation>(
+                                       bus, path, *this, id, extendedVersion,
+                                       activationState, associations)));
+
+            // If Active, create RedundancyPriority instance for this version.
+            if (activationState == server::Activation::Activations::Active)
+            {
+                uint8_t priority = std::numeric_limits<uint8_t>::max();
+                if (!restoreFromFile(id, priority))
+                {
+                    log<level::ERR>("Unable to restore priority from file.",
+                                    entry("VERSIONID=%s", id.c_str()));
+                }
+                activations.find(id)->second->redundancyPriority =
+                    std::make_unique<RedundancyPriority>(
+                        bus, path, *(activations.find(id)->second), priority);
+            }
+
+            // Create Version instance for this version.
+            auto versionPtr = std::make_unique<Version>(
+                bus, path, *this, id, version, purpose, "",
+                std::bind(&ItemUpdaterUbi::erase, this, std::placeholders::_1));
+            versionPtr->deleteObject =
+                std::make_unique<Delete>(bus, path, *versionPtr);
+            versions.insert(std::make_pair(id, std::move(versionPtr)));
+        }
+        else if (0 == iter.path().native().compare(0, PNOR_RW_PREFIX_LEN,
+                                                   PNOR_RW_PREFIX))
+        {
+            auto id = iter.path().native().substr(PNOR_RW_PREFIX_LEN);
+            auto roDir = PNOR_RO_PREFIX + id;
+            if (!fs::is_directory(roDir))
+            {
+                log<level::ERR>("No corresponding read-only volume found.",
+                                entry("DIRNAME=%s", roDir.c_str()));
+                ItemUpdaterUbi::erase(id);
+            }
+        }
+    }
+
+    // Look at the RO symlink to determine if there is a functional image
+    auto id = determineId(PNOR_RO_ACTIVE_PATH);
+    if (!id.empty())
+    {
+        updateFunctionalAssociation(id);
+    }
+    return;
+}
+
+int ItemUpdaterUbi::validateSquashFSImage(const std::string& filePath)
+{
+    auto file = fs::path(filePath) / squashFSImage;
+    if (fs::is_regular_file(file))
+    {
+        return 0;
+    }
+    else
+    {
+        log<level::ERR>("Failed to find the SquashFS image.");
+        return -1;
+    }
+}
+
+void ItemUpdaterUbi::removeReadOnlyPartition(std::string versionId)
+{
+    auto serviceFile = "obmc-flash-bios-ubiumount-ro@" + versionId + ".service";
+
+    // Remove the read-only partitions.
+    auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                      SYSTEMD_INTERFACE, "StartUnit");
+    method.append(serviceFile, "replace");
+    bus.call_noreply(method);
+}
+
+void ItemUpdaterUbi::removeReadWritePartition(std::string versionId)
+{
+    auto serviceFile = "obmc-flash-bios-ubiumount-rw@" + versionId + ".service";
+
+    // Remove the read-write partitions.
+    auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                      SYSTEMD_INTERFACE, "StartUnit");
+    method.append(serviceFile, "replace");
+    bus.call_noreply(method);
+}
+
+void ItemUpdaterUbi::reset()
+{
+    std::vector<uint8_t> mboxdArgs;
+
+    // Suspend mboxd - no args required.
+    auto dbusCall = bus.new_method_call(MBOXD_INTERFACE, MBOXD_PATH,
+                                        MBOXD_INTERFACE, "cmd");
+
+    dbusCall.append(static_cast<uint8_t>(3), mboxdArgs);
+
+    auto responseMsg = bus.call(dbusCall);
+    if (responseMsg.is_method_error())
+    {
+        log<level::ERR>("Error in mboxd suspend call");
+        elog<InternalFailure>();
+    }
+
+    constexpr static auto patchDir = "/usr/local/share/pnor";
+    if (fs::is_directory(patchDir))
+    {
+        for (const auto& iter : fs::directory_iterator(patchDir))
+        {
+            fs::remove_all(iter);
+        }
+    }
+
+    // Clear the read-write partitions.
+    for (const auto& it : activations)
+    {
+        auto rwDir = PNOR_RW_PREFIX + it.first;
+        if (fs::is_directory(rwDir))
+        {
+            for (const auto& iter : fs::directory_iterator(rwDir))
+            {
+                fs::remove_all(iter);
+            }
+        }
+    }
+
+    // Clear the preserved partition.
+    if (fs::is_directory(PNOR_PRSV))
+    {
+        for (const auto& iter : fs::directory_iterator(PNOR_PRSV))
+        {
+            fs::remove_all(iter);
+        }
+    }
+
+    // Resume mboxd with arg 1, indicating that the flash was modified.
+    dbusCall = bus.new_method_call(MBOXD_INTERFACE, MBOXD_PATH, MBOXD_INTERFACE,
+                                   "cmd");
+
+    mboxdArgs.push_back(1);
+    dbusCall.append(static_cast<uint8_t>(4), mboxdArgs);
+
+    responseMsg = bus.call(dbusCall);
+    if (responseMsg.is_method_error())
+    {
+        log<level::ERR>("Error in mboxd resume call");
+        elog<InternalFailure>();
+    }
+
+    return;
+}
+
+bool ItemUpdaterUbi::isVersionFunctional(const std::string& versionId)
+{
+    if (!fs::exists(PNOR_RO_ACTIVE_PATH))
+    {
+        return false;
+    }
+
+    fs::path activeRO = fs::read_symlink(PNOR_RO_ACTIVE_PATH);
+
+    if (!fs::is_directory(activeRO))
+    {
+        return false;
+    }
+
+    if (activeRO.string().find(versionId) == std::string::npos)
+    {
+        return false;
+    }
+
+    // active PNOR is the version we're checking
+    return true;
+}
+
+void ItemUpdaterUbi::freePriority(uint8_t value, const std::string& versionId)
+{
+    // TODO openbmc/openbmc#1896 Improve the performance of this function
+    for (const auto& intf : activations)
+    {
+        if (intf.second->redundancyPriority)
+        {
+            if (intf.second->redundancyPriority.get()->priority() == value &&
+                intf.second->versionId != versionId)
+            {
+                intf.second->redundancyPriority.get()->priority(value + 1);
+            }
+        }
+    }
+}
+
+bool ItemUpdaterUbi::isLowestPriority(uint8_t value)
+{
+    for (const auto& intf : activations)
+    {
+        if (intf.second->redundancyPriority)
+        {
+            if (intf.second->redundancyPriority.get()->priority() < value)
+            {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+bool ItemUpdaterUbi::erase(std::string entryId)
+{
+    if (!ItemUpdater::erase(entryId))
+    {
+        return false;
+    }
+
+    // Remove priority persistence file
+    removeFile(entryId);
+
+    // Removing read-only and read-write partitions
+    removeReadWritePartition(entryId);
+    removeReadOnlyPartition(entryId);
+
+    return true;
+}
+
+void ItemUpdaterUbi::deleteAll()
+{
+    auto chassisOn = isChassisOn();
+
+    for (const auto& activationIt : activations)
+    {
+        if (isVersionFunctional(activationIt.first) && chassisOn)
+        {
+            continue;
+        }
+        else
+        {
+            ItemUpdaterUbi::erase(activationIt.first);
+        }
+    }
+
+    // Remove any remaining pnor-ro- or pnor-rw- volumes that do not match
+    // the current version.
+    auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                      SYSTEMD_INTERFACE, "StartUnit");
+    method.append("obmc-flash-bios-cleanup.service", "replace");
+    bus.call_noreply(method);
+}
+
+// TODO: openbmc/openbmc#1402 Monitor flash usage
+void ItemUpdaterUbi::freeSpace()
+{
+    //  Versions with the highest priority in front
+    std::priority_queue<std::pair<int, std::string>,
+                        std::vector<std::pair<int, std::string>>,
+                        std::less<std::pair<int, std::string>>>
+        versionsPQ;
+
+    std::size_t count = 0;
+    for (const auto& iter : activations)
+    {
+        if (iter.second.get()->activation() ==
+            server::Activation::Activations::Active)
+        {
+            count++;
+            // Don't put the functional version on the queue since we can't
+            // remove the "running" PNOR version if it allows multiple PNORs
+            // But removing functional version if there is only one PNOR.
+            if (ACTIVE_PNOR_MAX_ALLOWED > 1 &&
+                isVersionFunctional(iter.second->versionId))
+            {
+                continue;
+            }
+            versionsPQ.push(std::make_pair(
+                iter.second->redundancyPriority.get()->priority(),
+                iter.second->versionId));
+        }
+    }
+
+    // If the number of PNOR versions is over ACTIVE_PNOR_MAX_ALLOWED -1,
+    // remove the highest priority one(s).
+    while ((count >= ACTIVE_PNOR_MAX_ALLOWED) && (!versionsPQ.empty()))
+    {
+        erase(versionsPQ.top().second);
+        versionsPQ.pop();
+        count--;
+    }
+}
+
+std::string ItemUpdater::determineId(const std::string& symlinkPath)
+{
+    if (!fs::exists(symlinkPath))
+    {
+        return {};
+    }
+
+    auto target = fs::canonical(symlinkPath).string();
+
+    // check to make sure the target really exists
+    if (!fs::is_regular_file(target + "/" + PNOR_TOC_FILE))
+    {
+        return {};
+    }
+    // Get the image <id> from the symlink target
+    // for example /media/ro-2a1022fe
+    static const auto PNOR_RO_PREFIX_LEN = strlen(PNOR_RO_PREFIX);
+    return target.substr(PNOR_RO_PREFIX_LEN);
+}
+
+void GardReset::reset()
+{
+    // The GARD partition is currently misspelled "GUARD." This file path will
+    // need to be updated in the future.
+    auto path = fs::path(PNOR_PRSV_ACTIVE_PATH);
+    path /= "GUARD";
+    std::vector<uint8_t> mboxdArgs;
+
+    auto dbusCall = bus.new_method_call(MBOXD_INTERFACE, MBOXD_PATH,
+                                        MBOXD_INTERFACE, "cmd");
+
+    // Suspend mboxd - no args required.
+    dbusCall.append(static_cast<uint8_t>(3), mboxdArgs);
+
+    auto responseMsg = bus.call(dbusCall);
+    if (responseMsg.is_method_error())
+    {
+        log<level::ERR>("Error in mboxd suspend call");
+        elog<InternalFailure>();
+    }
+
+    if (fs::is_regular_file(path))
+    {
+        fs::remove(path);
+    }
+
+    dbusCall = bus.new_method_call(MBOXD_INTERFACE, MBOXD_PATH, MBOXD_INTERFACE,
+                                   "cmd");
+
+    // Resume mboxd with arg 1, indicating that the flash is modified.
+    mboxdArgs.push_back(1);
+    dbusCall.append(static_cast<uint8_t>(4), mboxdArgs);
+
+    responseMsg = bus.call(dbusCall);
+    if (responseMsg.is_method_error())
+    {
+        log<level::ERR>("Error in mboxd resume call");
+        elog<InternalFailure>();
+    }
+}
+
+} // namespace updater
+} // namespace software
+} // namespace openpower
diff --git a/ubi/item_updater_ubi.hpp b/ubi/item_updater_ubi.hpp
new file mode 100644
index 0000000..af330a8
--- /dev/null
+++ b/ubi/item_updater_ubi.hpp
@@ -0,0 +1,85 @@
+#pragma once
+
+#include "item_updater.hpp"
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+
+/** @class ItemUpdaterUbi
+ *  @brief Manages the activation of the host version items for ubi layout
+ */
+class ItemUpdaterUbi : public ItemUpdater
+{
+  public:
+    ItemUpdaterUbi(sdbusplus::bus::bus& bus, const std::string& path) :
+        ItemUpdater(bus, path)
+    {
+        processPNORImage();
+        gardReset = std::make_unique<GardReset>(bus, GARD_PATH);
+        volatileEnable = std::make_unique<ObjectEnable>(bus, volatilePath);
+
+        // Emit deferred signal.
+        emit_object_added();
+    }
+    virtual ~ItemUpdaterUbi() = default;
+
+    void freePriority(uint8_t value, const std::string& versionId) override;
+
+    bool isLowestPriority(uint8_t value) override;
+
+    void processPNORImage() override;
+
+    bool erase(std::string entryId) override;
+
+    void deleteAll() override;
+
+    void freeSpace() override;
+
+    bool isVersionFunctional(const std::string& versionId) override;
+
+  private:
+    /** @brief Callback function for Software.Version match.
+     *  @details Creates an Activation D-Bus object.
+     *
+     * @param[in]  msg       - Data associated with subscribed signal
+     */
+    void createActivation(sdbusplus::message::message& msg) override;
+
+    /** @brief Host factory reset - clears PNOR partitions for each
+     * Activation D-Bus object */
+    void reset() override;
+
+    /**
+     * @brief Validates the presence of SquashFS image in the image dir.
+     *
+     * @param[in]  filePath - The path to the SquashFS image.
+     * @param[out] result    - 0 --> if validation was successful
+     *                       - -1--> Otherwise
+     */
+    static int validateSquashFSImage(const std::string& filePath);
+
+    /** @brief Clears read only PNOR partition for
+     *  given Activation D-Bus object
+     *
+     * @param[in]  versionId - The id of the ro partition to remove.
+     */
+    void removeReadOnlyPartition(std::string versionId);
+
+    /** @brief Clears read write PNOR partition for
+     *  given Activation D-Bus object
+     *
+     *  @param[in]  versionId - The id of the rw partition to remove.
+     */
+    void removeReadWritePartition(std::string versionId);
+
+    /** @brief Clears preserved PNOR partition */
+    void removePreservedPartition();
+};
+
+} // namespace updater
+} // namespace software
+} // namespace openpower
