diff --git a/extensions/openpower-pels/repository.cpp b/extensions/openpower-pels/repository.cpp
index 8458fcc..e608927 100644
--- a/extensions/openpower-pels/repository.cpp
+++ b/extensions/openpower-pels/repository.cpp
@@ -499,5 +499,180 @@
     }
 }
 
+std::vector<Repository::AttributesReference>
+    Repository::getAllPELAttributes(SortOrder order) const
+{
+    std::vector<Repository::AttributesReference> attributes;
+
+    std::for_each(
+        _pelAttributes.begin(), _pelAttributes.end(),
+        [&attributes](auto& pelEntry) { attributes.push_back(pelEntry); });
+
+    std::sort(attributes.begin(), attributes.end(),
+              [order](const auto& left, const auto& right) {
+                  if (order == SortOrder::ascending)
+                  {
+                      return left.get().second.path < right.get().second.path;
+                  }
+                  return left.get().second.path > right.get().second.path;
+              });
+
+    return attributes;
+}
+
+std::vector<uint32_t> Repository::prune()
+{
+    std::vector<uint32_t> obmcLogIDs;
+    std::string msg = "Pruning PEL repository that takes up " +
+                      std::to_string(_sizes.total) + " bytes and has " +
+                      std::to_string(_pelAttributes.size()) + " PELs";
+    log<level::INFO>(msg.c_str());
+
+    // Set up the 5 functions to check if the PEL category
+    // is still over its limits.
+
+    // BMC informational PELs should only take up 15%
+    IsOverLimitFunc overBMCInfoLimit = [this]() {
+        return _sizes.bmcInfo > _maxRepoSize * 15 / 100;
+    };
+
+    // BMC non informational PELs should only take up 30%
+    IsOverLimitFunc overBMCNonInfoLimit = [this]() {
+        return _sizes.bmcServiceable > _maxRepoSize * 30 / 100;
+    };
+
+    // Non BMC informational PELs should only take up 15%
+    IsOverLimitFunc overNonBMCInfoLimit = [this]() {
+        return _sizes.nonBMCInfo > _maxRepoSize * 15 / 100;
+    };
+
+    // Non BMC non informational PELs should only take up 15%
+    IsOverLimitFunc overNonBMCNonInfoLimit = [this]() {
+        return _sizes.nonBMCServiceable > _maxRepoSize * 30 / 100;
+    };
+
+    // Bring the total number of PELs down to 80% of the max
+    IsOverLimitFunc tooManyPELsLimit = [this]() {
+        return _pelAttributes.size() > _maxNumPELs * 80 / 100;
+    };
+
+    // Set up the functions to determine which category a PEL is in.
+    // TODO: Return false in these functions if a PEL caused a guard record.
+
+    // A BMC informational PEL
+    IsPELTypeFunc isBMCInfo = [](const PELAttributes& pel) {
+        return (CreatorID::openBMC == static_cast<CreatorID>(pel.creator)) &&
+               !Repository::isServiceableSev(pel);
+    };
+
+    // A BMC non informational PEL
+    IsPELTypeFunc isBMCNonInfo = [](const PELAttributes& pel) {
+        return (CreatorID::openBMC == static_cast<CreatorID>(pel.creator)) &&
+               Repository::isServiceableSev(pel);
+    };
+
+    // A non BMC informational PEL
+    IsPELTypeFunc isNonBMCInfo = [](const PELAttributes& pel) {
+        return (CreatorID::openBMC != static_cast<CreatorID>(pel.creator)) &&
+               !Repository::isServiceableSev(pel);
+    };
+
+    // A non BMC non informational PEL
+    IsPELTypeFunc isNonBMCNonInfo = [](const PELAttributes& pel) {
+        return (CreatorID::openBMC != static_cast<CreatorID>(pel.creator)) &&
+               Repository::isServiceableSev(pel);
+    };
+
+    // When counting PELs, count every PEL
+    IsPELTypeFunc isAnyPEL = [](const PELAttributes& pel) { return true; };
+
+    // Check all 4 categories, which will result in at most 90%
+    // usage (15 + 30 + 15 + 30).
+    removePELs(overBMCInfoLimit, isBMCInfo, obmcLogIDs);
+    removePELs(overBMCNonInfoLimit, isBMCNonInfo, obmcLogIDs);
+    removePELs(overNonBMCInfoLimit, isNonBMCInfo, obmcLogIDs);
+    removePELs(overNonBMCNonInfoLimit, isNonBMCNonInfo, obmcLogIDs);
+
+    // After the above pruning check if there are still too many PELs,
+    // which can happen depending on PEL sizes.
+    if (_pelAttributes.size() > _maxNumPELs)
+    {
+        removePELs(tooManyPELsLimit, isAnyPEL, obmcLogIDs);
+    }
+
+    if (!obmcLogIDs.empty())
+    {
+        std::string msg = "Number of PELs removed to save space: " +
+                          std::to_string(obmcLogIDs.size());
+        log<level::INFO>(msg.c_str());
+    }
+
+    return obmcLogIDs;
+}
+
+void Repository::removePELs(IsOverLimitFunc& isOverLimit,
+                            IsPELTypeFunc& isPELType,
+                            std::vector<uint32_t>& removedBMCLogIDs)
+{
+    if (!isOverLimit())
+    {
+        return;
+    }
+
+    auto attributes = getAllPELAttributes(SortOrder::ascending);
+
+    // Make 4 passes on the PELs, stopping as soon as isOverLimit
+    // returns false.
+    //   Pass 1: only delete HMC acked PELs
+    //   Pass 2: only delete OS acked PELs
+    //   Pass 3: only delete PHYP sent PELs
+    //   Pass 4: delete all PELs
+    static const std::vector<std::function<bool(const PELAttributes& pel)>>
+        stateChecks{[](const auto& pel) {
+                        return pel.hmcState == TransmissionState::acked;
+                    },
+
+                    [](const auto& pel) {
+                        return pel.hostState == TransmissionState::acked;
+                    },
+
+                    [](const auto& pel) {
+                        return pel.hostState == TransmissionState::sent;
+                    },
+
+                    [](const auto& pel) { return true; }};
+
+    for (const auto& stateCheck : stateChecks)
+    {
+        for (auto it = attributes.begin(); it != attributes.end();)
+        {
+            const auto& pel = it->get();
+            if (isPELType(pel.second) && stateCheck(pel.second))
+            {
+                auto removedID = pel.first.obmcID.id;
+                remove(pel.first);
+
+                removedBMCLogIDs.push_back(removedID);
+
+                attributes.erase(it);
+
+                if (!isOverLimit())
+                {
+                    break;
+                }
+            }
+            else
+            {
+                ++it;
+            }
+        }
+
+        if (!isOverLimit())
+        {
+            break;
+        }
+    }
+}
+
 } // namespace pels
 } // namespace openpower
