diff --git a/Makefile.am b/Makefile.am
index e012ae5..c924948 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,6 +14,12 @@
 	item_updater.cpp \
 	item_updater_main.cpp
 
+if UBIFS_LAYOUT
+include ubi/Makefile.am.include
+else
+include static/Makefile.am.include
+endif
+
 if WANT_SIGNATURE_VERIFY_BUILD
 openpower_update_manager_SOURCES += \
 	image_verify.cpp \
diff --git a/configure.ac b/configure.ac
index f2d8766..0213ed4 100755
--- a/configure.ac
+++ b/configure.ac
@@ -146,6 +146,14 @@
 AC_DEFINE(PNOR_PRSV_ACTIVE_PATH, "/var/lib/phosphor-software-manager/pnor/prsv",
     [Path to the active preserved pnor partitions])
 
+# Setup ubifs layout support
+# For now make it default enabled
+AC_ARG_ENABLE([ubifs_layout],
+    AS_HELP_STRING([--disable-ubifs_layout], [Disable ubifs support.]))
+AS_IF([test "x$enable_ubifs_layout" != "xno"], \
+    [AC_DEFINE([UBIFS_LAYOUT],[],[Enable ubifs support.])])
+AM_CONDITIONAL([UBIFS_LAYOUT], [test "x$enable_ubifs_layout" != "xno"])
+
 AC_ARG_VAR(ACTIVE_PNOR_MAX_ALLOWED, [The maximum allowed active pnor versions])
 AS_IF([test "x$ACTIVE_PNOR_MAX_ALLOWED" == "x"], [ACTIVE_PNOR_MAX_ALLOWED=2])
 AC_DEFINE_UNQUOTED([ACTIVE_PNOR_MAX_ALLOWED], [$ACTIVE_PNOR_MAX_ALLOWED], [The maximum allowed active pnor versions])
diff --git a/item_updater.cpp b/item_updater.cpp
index f920661..06f3bc8 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -2,18 +2,10 @@
 
 #include "item_updater.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
 {
@@ -21,357 +13,91 @@
 {
 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 ItemUpdater::createActivation(sdbusplus::message::message& m)
+void ItemUpdater::createActiveAssociation(const std::string& path)
 {
-    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 (ItemUpdater::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(&ItemUpdater::erase, this, std::placeholders::_1));
-        versionPtr->deleteObject =
-            std::make_unique<Delete>(bus, path, *versionPtr);
-        versions.insert(std::make_pair(versionId, std::move(versionPtr)));
-    }
-    return;
+    assocs.emplace_back(
+        std::make_tuple(ACTIVE_FWD_ASSOCIATION, ACTIVE_REV_ASSOCIATION, path));
+    associations(assocs);
 }
 
-void ItemUpdater::processPNORImage()
+void ItemUpdater::updateFunctionalAssociation(const std::string& versionId)
 {
-    // Read pnor.toc from folders under /media/
-    // to get Active Software Versions.
-    for (const auto& iter : fs::directory_iterator(MEDIA_DIR))
+    std::string path = std::string{SOFTWARE_OBJPATH} + '/' + versionId;
+    // remove all functional associations
+    for (auto iter = assocs.begin(); iter != assocs.end();)
     {
-        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))
+        if ((std::get<0>(*iter)).compare(FUNCTIONAL_FWD_ASSOCIATION) == 0)
         {
-            // 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()));
-                ItemUpdater::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(&ItemUpdater::erase, this, std::placeholders::_1));
-            versionPtr->deleteObject =
-                std::make_unique<Delete>(bus, path, *versionPtr);
-            versions.insert(std::make_pair(id, std::move(versionPtr)));
+            iter = assocs.erase(iter);
         }
-        else if (0 == iter.path().native().compare(0, PNOR_RW_PREFIX_LEN,
-                                                   PNOR_RW_PREFIX))
+        else
         {
-            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()));
-                ItemUpdater::erase(id);
-            }
+            ++iter;
         }
     }
-
-    // Look at the RO symlink to determine if there is a functional image
-    auto id = determineId(PNOR_RO_ACTIVE_PATH);
-    if (!id.empty())
-    {
-        updateFunctionalAssociation(std::string{SOFTWARE_OBJPATH} + '/' + id);
-    }
-    return;
+    assocs.emplace_back(std::make_tuple(FUNCTIONAL_FWD_ASSOCIATION,
+                                        FUNCTIONAL_REV_ASSOCIATION, path));
+    associations(assocs);
 }
 
-int ItemUpdater::validateSquashFSImage(const std::string& filePath)
+void ItemUpdater::removeAssociation(const std::string& path)
 {
-    auto file = fs::path(filePath) / squashFSImage;
-    if (fs::is_regular_file(file))
+    for (auto iter = assocs.begin(); iter != assocs.end();)
     {
-        return 0;
+        if ((std::get<2>(*iter)).compare(path) == 0)
+        {
+            iter = assocs.erase(iter);
+            associations(assocs);
+        }
+        else
+        {
+            ++iter;
+        }
+    }
+}
+
+bool ItemUpdater::erase(std::string entryId)
+{
+    if (isVersionFunctional(entryId) && isChassisOn())
+    {
+        log<level::ERR>(("Error: Version " + entryId +
+                         " is currently active and running on the host."
+                         " Unable to remove.")
+                            .c_str());
+        return false;
+    }
+
+    // Removing entry in versions map
+    auto it = versions.find(entryId);
+    if (it == versions.end())
+    {
+        log<level::ERR>(("Error: Failed to find version " + entryId +
+                         " in item updater versions map."
+                         " Unable to remove.")
+                            .c_str());
     }
     else
     {
-        log<level::ERR>("Failed to find the SquashFS image.");
-        return -1;
+        versions.erase(entryId);
     }
-}
 
-void ItemUpdater::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 ItemUpdater::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 ItemUpdater::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())
+    // Removing entry in activations map
+    auto ita = activations.find(entryId);
+    if (ita == activations.end())
     {
-        log<level::ERR>("Error in mboxd suspend call");
-        elog<InternalFailure>();
+        log<level::ERR>(("Error: Failed to find version " + entryId +
+                         " in item updater activations map."
+                         " Unable to remove.")
+                            .c_str());
     }
-
-    constexpr static auto patchDir = "/usr/local/share/pnor";
-    if (fs::is_directory(patchDir))
+    else
     {
-        for (const auto& iter : fs::directory_iterator(patchDir))
-        {
-            fs::remove_all(iter);
-        }
+        removeAssociation(ita->second->path);
+        activations.erase(entryId);
     }
-
-    // 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 ItemUpdater::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;
 }
 
@@ -416,252 +142,6 @@
     return (strParam != CHASSIS_STATE_OFF);
 }
 
-void ItemUpdater::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 ItemUpdater::isLowestPriority(uint8_t value)
-{
-    for (const auto& intf : activations)
-    {
-        if (intf.second->redundancyPriority)
-        {
-            if (intf.second->redundancyPriority.get()->priority() < value)
-            {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-void ItemUpdater::erase(std::string entryId)
-{
-    if (isVersionFunctional(entryId) && isChassisOn())
-    {
-        log<level::ERR>(("Error: Version " + entryId +
-                         " is currently active and running on the host."
-                         " Unable to remove.")
-                            .c_str());
-        return;
-    }
-    // Remove priority persistence file
-    removeFile(entryId);
-
-    // Removing read-only and read-write partitions
-    removeReadWritePartition(entryId);
-    removeReadOnlyPartition(entryId);
-
-    // Removing entry in versions map
-    auto it = versions.find(entryId);
-    if (it == versions.end())
-    {
-        log<level::ERR>(("Error: Failed to find version " + entryId +
-                         " in item updater versions map."
-                         " Unable to remove.")
-                            .c_str());
-    }
-    else
-    {
-        versions.erase(entryId);
-    }
-
-    // Removing entry in activations map
-    auto ita = activations.find(entryId);
-    if (ita == activations.end())
-    {
-        log<level::ERR>(("Error: Failed to find version " + entryId +
-                         " in item updater activations map."
-                         " Unable to remove.")
-                            .c_str());
-    }
-    else
-    {
-        removeAssociation(ita->second->path);
-        activations.erase(entryId);
-    }
-    return;
-}
-
-void ItemUpdater::deleteAll()
-{
-    auto chassisOn = isChassisOn();
-
-    for (const auto& activationIt : activations)
-    {
-        if (isVersionFunctional(activationIt.first) && chassisOn)
-        {
-            continue;
-        }
-        else
-        {
-            ItemUpdater::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 ItemUpdater::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--;
-    }
-}
-
-void ItemUpdater::createActiveAssociation(const std::string& path)
-{
-    assocs.emplace_back(
-        std::make_tuple(ACTIVE_FWD_ASSOCIATION, ACTIVE_REV_ASSOCIATION, path));
-    associations(assocs);
-}
-
-void ItemUpdater::updateFunctionalAssociation(const std::string& path)
-{
-    // remove all functional associations
-    for (auto iter = assocs.begin(); iter != assocs.end();)
-    {
-        if ((std::get<0>(*iter)).compare(FUNCTIONAL_FWD_ASSOCIATION) == 0)
-        {
-            iter = assocs.erase(iter);
-        }
-        else
-        {
-            ++iter;
-        }
-    }
-    assocs.emplace_back(std::make_tuple(FUNCTIONAL_FWD_ASSOCIATION,
-                                        FUNCTIONAL_REV_ASSOCIATION, path));
-    associations(assocs);
-}
-
-void ItemUpdater::removeAssociation(const std::string& path)
-{
-    for (auto iter = assocs.begin(); iter != assocs.end();)
-    {
-        if ((std::get<2>(*iter)).compare(path) == 0)
-        {
-            iter = assocs.erase(iter);
-            associations(assocs);
-        }
-        else
-        {
-            ++iter;
-        }
-    }
-}
-
-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/item_updater.hpp b/item_updater.hpp
index 1dc0868..96ef29c 100644
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -89,14 +89,10 @@
                      std::bind(std::mem_fn(&ItemUpdater::createActivation),
                                this, std::placeholders::_1))
     {
-        processPNORImage();
-        gardReset = std::make_unique<GardReset>(bus, GARD_PATH);
-        volatileEnable = std::make_unique<ObjectEnable>(bus, volatilePath);
-
-        // Emit deferred signal.
-        emit_object_added();
     }
 
+    virtual ~ItemUpdater() = default;
+
     /** @brief Sets the given priority free by incrementing
      *  any existing priority with the same value by 1
      *
@@ -105,7 +101,7 @@
      *                         are trying to free up the priority.
      *  @return None
      */
-    void freePriority(uint8_t value, const std::string& versionId);
+    virtual void freePriority(uint8_t value, const std::string& versionId) = 0;
 
     /** @brief Determine is the given priority is the lowest
      *
@@ -114,25 +110,25 @@
      *  @return boolean corresponding to whether the given
      *           priority is lowest.
      */
-    bool isLowestPriority(uint8_t value);
+    virtual bool isLowestPriority(uint8_t value) = 0;
 
     /**
      * @brief Create and populate the active PNOR Version.
      */
-    void processPNORImage();
+    virtual void processPNORImage() = 0;
 
     /** @brief Deletes version
      *
      *  @param[in] entryId - Id of the version to delete
      *
-     *  @return None
+     *  @return - Returns true if the version is deleted.
      */
-    void erase(std::string entryId);
+    virtual bool erase(std::string entryId);
 
     /**
      * @brief Erases any non-active pnor versions.
      */
-    void deleteAll();
+    virtual void deleteAll() = 0;
 
     /** @brief Brings the total number of active PNOR versions to
      *         ACTIVE_PNOR_MAX_ALLOWED -1. This function is intended to be
@@ -141,7 +137,7 @@
      *         version(s) with the highest priority, skipping the
      *         functional PNOR version.
      */
-    void freeSpace();
+    virtual void freeSpace() = 0;
 
     /** @brief Determine the software version id
      *         from the symlink target (e.g. /media/ro-2a1022fe).
@@ -156,20 +152,20 @@
      *
      * @param[in]  path - The path to create the association to.
      */
-    void createActiveAssociation(const std::string& path);
+    virtual void createActiveAssociation(const std::string& path);
 
     /** @brief Updates the functional association to the
      *  new "running" PNOR image
      *
-     * @param[in]  path - The path to update the association to.
+     * @param[in]  versionId - The id of the image to update the association to.
      */
-    void updateFunctionalAssociation(const std::string& path);
+    virtual void updateFunctionalAssociation(const std::string& versionId);
 
     /** @brief Removes the associations from the provided software image path
      *
      * @param[in]  path - The path to remove the association from.
      */
-    void removeAssociation(const std::string& path);
+    virtual void removeAssociation(const std::string& path);
 
     /** @brief Persistent GardReset dbus object */
     std::unique_ptr<GardReset> gardReset;
@@ -180,27 +176,18 @@
      *
      * @return - Returns true if this version is currently functional.
      */
-    static bool isVersionFunctional(const std::string& versionId);
+    virtual bool isVersionFunctional(const std::string& versionId) = 0;
 
     /** @brief Persistent ObjectEnable D-Bus object */
     std::unique_ptr<ObjectEnable> volatileEnable;
 
-  private:
+  protected:
     /** @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);
-
-    /**
-     * @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);
+    virtual void createActivation(sdbusplus::message::message& msg) = 0;
 
     /** @brief Persistent sdbusplus D-Bus bus connection. */
     sdbusplus::bus::bus& bus;
@@ -219,26 +206,9 @@
     /** @brief This entry's associations */
     AssociationList assocs = {};
 
-    /** @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();
-
     /** @brief Host factory reset - clears PNOR partitions for each
      * Activation D-Bus object */
-    void reset() override;
+    void reset() override = 0;
 
     /** @brief Check whether the host is running
      *
diff --git a/item_updater_main.cpp b/item_updater_main.cpp
index d773142..d0d7554 100644
--- a/item_updater_main.cpp
+++ b/item_updater_main.cpp
@@ -1,6 +1,8 @@
 #include "config.h"
 
-#include "item_updater.hpp"
+#ifdef UBIFS_LAYOUT
+#include "ubi/item_updater_ubi.hpp"
+#endif
 #include "watch.hpp"
 
 #include <phosphor-logging/log.hpp>
@@ -26,7 +28,9 @@
     // Add sdbusplus ObjectManager.
     sdbusplus::server::manager::manager objManager(bus, SOFTWARE_OBJPATH);
 
-    ItemUpdater updater(bus, SOFTWARE_OBJPATH);
+#ifdef UBIFS_LAYOUT
+    ItemUpdaterUbi updater(bus, SOFTWARE_OBJPATH);
+#endif
 
     bus.request_name(BUSNAME_UPDATER);
     try
diff --git a/static/Makefile.am.include b/static/Makefile.am.include
new file mode 100644
index 0000000..73f96e3
--- /dev/null
+++ b/static/Makefile.am.include
@@ -0,0 +1,2 @@
+openpower_update_manager_SOURCES += \
+	%reldir%/item_updater.cpp
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
diff --git a/watch.cpp b/watch.cpp
index 35cbb15..192d3d9 100644
--- a/watch.cpp
+++ b/watch.cpp
@@ -26,7 +26,7 @@
 namespace fs = std::experimental::filesystem;
 
 Watch::Watch(sd_event* loop,
-             std::function<void(std::string&)> functionalCallback) :
+             std::function<void(const std::string&)> functionalCallback) :
     functionalCallback(functionalCallback),
     fd(inotifyInit())
 
@@ -94,9 +94,7 @@
         if (fs::equivalent(path, PNOR_RO_ACTIVE_PATH))
         {
             auto id = ItemUpdater::determineId(path);
-            auto objPath = std::string{SOFTWARE_OBJPATH} + '/' + id;
-
-            static_cast<Watch*>(userdata)->functionalCallback(objPath);
+            static_cast<Watch*>(userdata)->functionalCallback(id);
         }
         offset += offsetof(inotify_event, name) + event->len;
     }
diff --git a/watch.hpp b/watch.hpp
index f7ae6af..a04967e 100644
--- a/watch.hpp
+++ b/watch.hpp
@@ -80,7 +80,8 @@
      *  @param[in] functionalCallback - The callback function for updating
      *                                  the functional associations.
      */
-    Watch(sd_event* loop, std::function<void(std::string&)> functionalCallback);
+    Watch(sd_event* loop,
+          std::function<void(const std::string&)> functionalCallback);
 
     Watch(const Watch&) = delete;
     Watch& operator=(const Watch&) = delete;
