diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp
index d6c404d..c741727 100644
--- a/extensions/openpower-pels/pel.cpp
+++ b/extensions/openpower-pels/pel.cpp
@@ -27,6 +27,9 @@
 #include "stream.hpp"
 #include "user_data_formats.hpp"
 
+#include <sys/stat.h>
+#include <unistd.h>
+
 #include <iostream>
 #include <phosphor-logging/log.hpp>
 
@@ -474,10 +477,116 @@
     return makeJSONUserDataSection(json);
 }
 
+std::vector<uint8_t> readFD(int fd)
+{
+    std::vector<uint8_t> data;
+
+    // Get the size
+    struct stat s;
+    int r = fstat(fd, &s);
+    if (r != 0)
+    {
+        auto e = errno;
+        log<level::ERR>("Could not get FFDC file size from FD",
+                        entry("ERRNO=%d", e));
+        return data;
+    }
+
+    if (0 == s.st_size)
+    {
+        log<level::ERR>("FFDC file is empty");
+        return data;
+    }
+
+    data.resize(s.st_size);
+
+    // Make sure its at the beginning, as maybe another
+    // extension already used it.
+    r = lseek(fd, 0, SEEK_SET);
+    if (r == -1)
+    {
+        auto e = errno;
+        log<level::ERR>("Could not seek to beginning of FFDC file",
+                        entry("ERRNO=%d", e));
+        return data;
+    }
+
+    r = read(fd, data.data(), s.st_size);
+    if (r == -1)
+    {
+        auto e = errno;
+        log<level::ERR>("Could not read FFDC file", entry("ERRNO=%d", e));
+    }
+    else if (r != s.st_size)
+    {
+        log<level::WARNING>("Could not read full FFDC file",
+                            entry("FILE_SIZE=%d", s.st_size),
+                            entry("SIZE_READ=%d", r));
+    }
+
+    return data;
+}
+
 std::unique_ptr<UserData> makeFFDCuserDataSection(uint16_t componentID,
                                                   const PelFFDCfile& file)
 {
-    return std::unique_ptr<UserData>();
+    auto data = readFD(file.fd);
+
+    if (data.empty())
+    {
+        return std::unique_ptr<UserData>();
+    }
+
+    // The data needs 4 Byte alignment, and save amount padded for the
+    // CBOR case.
+    uint32_t pad = 0;
+    while (data.size() % 4)
+    {
+        data.push_back(0);
+        pad++;
+    }
+
+    // For JSON, CBOR, and Text use our component ID, subType, and version,
+    // otherwise use the supplied ones.
+    uint16_t compID = static_cast<uint16_t>(ComponentID::phosphorLogging);
+    uint8_t subType{};
+    uint8_t version{};
+
+    switch (file.format)
+    {
+        case UserDataFormat::json:
+            subType = static_cast<uint8_t>(UserDataFormat::json);
+            version = static_cast<uint8_t>(UserDataFormatVersion::json);
+            break;
+        case UserDataFormat::cbor:
+            subType = static_cast<uint8_t>(UserDataFormat::cbor);
+            version = static_cast<uint8_t>(UserDataFormatVersion::cbor);
+
+            // The CBOR parser will fail on the extra pad bytes since they
+            // aren't CBOR.  Add the amount we padded to the end and other
+            // code will remove it all before parsing.
+            {
+                data.resize(data.size() + 4);
+                Stream stream{data};
+                stream.offset(data.size() - 4);
+                stream << pad;
+            }
+
+            break;
+        case UserDataFormat::text:
+            subType = static_cast<uint8_t>(UserDataFormat::text);
+            version = static_cast<uint8_t>(UserDataFormatVersion::text);
+            break;
+        case UserDataFormat::custom:
+        default:
+            // Use the passed in values
+            compID = componentID;
+            subType = file.subType;
+            version = file.version;
+            break;
+    }
+
+    return std::make_unique<UserData>(compID, subType, version, data);
 }
 
 } // namespace util
diff --git a/test/openpower-pels/pel_test.cpp b/test/openpower-pels/pel_test.cpp
index c5a1571..c6a29b6 100644
--- a/test/openpower-pels/pel_test.cpp
+++ b/test/openpower-pels/pel_test.cpp
@@ -33,6 +33,27 @@
 {
 };
 
+fs::path makeTempDir()
+{
+    char path[] = "/tmp/tempdirXXXXXX";
+    std::filesystem::path dir = mkdtemp(path);
+    return dir;
+}
+
+int writeFileAndGetFD(const fs::path& dir, const std::vector<uint8_t>& data)
+{
+    static size_t count = 0;
+    fs::path path = dir / (std::string{"file"} + std::to_string(count));
+    std::ofstream stream{path};
+    count++;
+
+    stream.write(reinterpret_cast<const char*>(data.data()), data.size());
+    stream.close();
+
+    FILE* fp = fopen(path.c_str(), "r");
+    return fileno(fp);
+}
+
 TEST_F(PELTest, FlattenTest)
 {
     auto data = pelDataFactory(TestPELType::pelSimple);
@@ -441,3 +462,308 @@
         }
     }
 }
+
+PelFFDCfile getJSONFFDC(const fs::path& dir)
+{
+    PelFFDCfile ffdc;
+    ffdc.format = UserDataFormat::json;
+    ffdc.subType = 5;
+    ffdc.version = 42;
+
+    auto inputJSON = R"({
+        "key1": "value1",
+        "key2": 42,
+        "key3" : [1, 2, 3, 4, 5],
+        "key4": {"key5": "value5"}
+    })"_json;
+
+    // Write the JSON to a file and get its descriptor.
+    auto s = inputJSON.dump();
+    std::vector<uint8_t> data{s.begin(), s.end()};
+    ffdc.fd = writeFileAndGetFD(dir, data);
+
+    return ffdc;
+}
+
+TEST_F(PELTest, MakeJSONFileUDSectionTest)
+{
+    auto dir = makeTempDir();
+
+    {
+        auto ffdc = getJSONFFDC(dir);
+
+        auto ud = util::makeFFDCuserDataSection(0x2002, ffdc);
+        close(ffdc.fd);
+        ASSERT_TRUE(ud);
+        ASSERT_TRUE(ud->valid());
+        EXPECT_EQ(ud->header().id, 0x5544);
+
+        EXPECT_EQ(ud->header().version,
+                  static_cast<uint8_t>(UserDataFormatVersion::json));
+        EXPECT_EQ(ud->header().subType,
+                  static_cast<uint8_t>(UserDataFormat::json));
+        EXPECT_EQ(ud->header().componentID,
+                  static_cast<uint16_t>(ComponentID::phosphorLogging));
+
+        // Pull the JSON back out of the the UserData section
+        const auto& d = ud->data();
+        std::string js{d.begin(), d.end()};
+        auto json = nlohmann::json::parse(js);
+
+        EXPECT_EQ("value1", json["key1"].get<std::string>());
+        EXPECT_EQ(42, json["key2"].get<int>());
+
+        std::vector<int> key3Values{1, 2, 3, 4, 5};
+        EXPECT_EQ(key3Values, json["key3"].get<std::vector<int>>());
+
+        std::map<std::string, std::string> key4Values{{"key5", "value5"}};
+        auto actual = json["key4"].get<std::map<std::string, std::string>>();
+        EXPECT_EQ(key4Values, actual);
+    }
+
+    {
+        // A bad FD
+        PelFFDCfile ffdc;
+        ffdc.format = UserDataFormat::json;
+        ffdc.subType = 5;
+        ffdc.version = 42;
+        ffdc.fd = 10000;
+
+        // The section shouldn't get made
+        auto ud = util::makeFFDCuserDataSection(0x2002, ffdc);
+        ASSERT_FALSE(ud);
+    }
+
+    fs::remove_all(dir);
+}
+
+PelFFDCfile getCBORFFDC(const fs::path& dir)
+{
+    PelFFDCfile ffdc;
+    ffdc.format = UserDataFormat::cbor;
+    ffdc.subType = 5;
+    ffdc.version = 42;
+
+    auto inputJSON = R"({
+        "key1": "value1",
+        "key2": 42,
+        "key3" : [1, 2, 3, 4, 5],
+        "key4": {"key5": "value5"}
+    })"_json;
+
+    // Convert the JSON to CBOR and write it to a file
+    auto data = nlohmann::json::to_cbor(inputJSON);
+    ffdc.fd = writeFileAndGetFD(dir, data);
+
+    return ffdc;
+}
+
+TEST_F(PELTest, MakeCBORFileUDSectionTest)
+{
+    auto dir = makeTempDir();
+
+    auto ffdc = getCBORFFDC(dir);
+    auto ud = util::makeFFDCuserDataSection(0x2002, ffdc);
+    close(ffdc.fd);
+    ASSERT_TRUE(ud);
+    ASSERT_TRUE(ud->valid());
+    EXPECT_EQ(ud->header().id, 0x5544);
+
+    EXPECT_EQ(ud->header().version,
+              static_cast<uint8_t>(UserDataFormatVersion::cbor));
+    EXPECT_EQ(ud->header().subType, static_cast<uint8_t>(UserDataFormat::cbor));
+    EXPECT_EQ(ud->header().componentID,
+              static_cast<uint16_t>(ComponentID::phosphorLogging));
+
+    // Pull the CBOR back out of the PEL section
+    // The number of pad bytes to make the section be 4B aligned
+    // was added at the end, read it and then remove it and the
+    // padding before parsing it.
+    auto data = ud->data();
+    Stream stream{data};
+    stream.offset(data.size() - 4);
+    uint32_t pad;
+    stream >> pad;
+
+    data.resize(data.size() - 4 - pad);
+
+    auto json = nlohmann::json::from_cbor(data);
+
+    EXPECT_EQ("value1", json["key1"].get<std::string>());
+    EXPECT_EQ(42, json["key2"].get<int>());
+
+    std::vector<int> key3Values{1, 2, 3, 4, 5};
+    EXPECT_EQ(key3Values, json["key3"].get<std::vector<int>>());
+
+    std::map<std::string, std::string> key4Values{{"key5", "value5"}};
+    auto actual = json["key4"].get<std::map<std::string, std::string>>();
+    EXPECT_EQ(key4Values, actual);
+
+    fs::remove_all(dir);
+}
+
+PelFFDCfile getTextFFDC(const fs::path& dir)
+{
+    PelFFDCfile ffdc;
+    ffdc.format = UserDataFormat::text;
+    ffdc.subType = 5;
+    ffdc.version = 42;
+
+    std::string text{"this is some text that will be used for FFDC"};
+    std::vector<uint8_t> data{text.begin(), text.end()};
+
+    ffdc.fd = writeFileAndGetFD(dir, data);
+
+    return ffdc;
+}
+
+TEST_F(PELTest, MakeTextFileUDSectionTest)
+{
+    auto dir = makeTempDir();
+
+    auto ffdc = getTextFFDC(dir);
+    auto ud = util::makeFFDCuserDataSection(0x2002, ffdc);
+    close(ffdc.fd);
+    ASSERT_TRUE(ud);
+    ASSERT_TRUE(ud->valid());
+    EXPECT_EQ(ud->header().id, 0x5544);
+
+    EXPECT_EQ(ud->header().version,
+              static_cast<uint8_t>(UserDataFormatVersion::text));
+    EXPECT_EQ(ud->header().subType, static_cast<uint8_t>(UserDataFormat::text));
+    EXPECT_EQ(ud->header().componentID,
+              static_cast<uint16_t>(ComponentID::phosphorLogging));
+
+    // Get the text back out
+    std::string text{ud->data().begin(), ud->data().end()};
+    EXPECT_EQ(text, "this is some text that will be used for FFDC");
+
+    fs::remove_all(dir);
+}
+
+PelFFDCfile getCustomFFDC(const fs::path& dir, const std::vector<uint8_t>& data)
+{
+    PelFFDCfile ffdc;
+    ffdc.format = UserDataFormat::custom;
+    ffdc.subType = 5;
+    ffdc.version = 42;
+
+    ffdc.fd = writeFileAndGetFD(dir, data);
+
+    return ffdc;
+}
+
+TEST_F(PELTest, MakeCustomFileUDSectionTest)
+{
+    auto dir = makeTempDir();
+
+    {
+        std::vector<uint8_t> data{1, 2, 3, 4, 5, 6, 7, 8};
+
+        auto ffdc = getCustomFFDC(dir, data);
+        auto ud = util::makeFFDCuserDataSection(0x2002, ffdc);
+        close(ffdc.fd);
+        ASSERT_TRUE(ud);
+        ASSERT_TRUE(ud->valid());
+        EXPECT_EQ(ud->header().size, 8 + 8); // data size + header size
+        EXPECT_EQ(ud->header().id, 0x5544);
+
+        EXPECT_EQ(ud->header().version, 42);
+        EXPECT_EQ(ud->header().subType, 5);
+        EXPECT_EQ(ud->header().componentID, 0x2002);
+
+        // Get the data back out
+        std::vector<uint8_t> newData{ud->data().begin(), ud->data().end()};
+        EXPECT_EQ(data, newData);
+    }
+
+    // Do the same thing again, but make it be non 4B aligned
+    // so the data gets padded.
+    {
+        std::vector<uint8_t> data{1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+        auto ffdc = getCustomFFDC(dir, data);
+        auto ud = util::makeFFDCuserDataSection(0x2002, ffdc);
+        close(ffdc.fd);
+        ASSERT_TRUE(ud);
+        ASSERT_TRUE(ud->valid());
+        EXPECT_EQ(ud->header().size, 12 + 8); // data size + header size
+        EXPECT_EQ(ud->header().id, 0x5544);
+
+        EXPECT_EQ(ud->header().version, 42);
+        EXPECT_EQ(ud->header().subType, 5);
+        EXPECT_EQ(ud->header().componentID, 0x2002);
+
+        // Get the data back out
+        std::vector<uint8_t> newData{ud->data().begin(), ud->data().end()};
+
+        // pad the original to 12B so we can compare
+        data.push_back(0);
+        data.push_back(0);
+        data.push_back(0);
+
+        EXPECT_EQ(data, newData);
+    }
+
+    fs::remove_all(dir);
+}
+
+// Test Adding FFDC from files to a PEL
+TEST_F(PELTest, CreateWithFFDCTest)
+{
+    auto dir = makeTempDir();
+    message::Entry regEntry;
+    uint64_t timestamp = 5;
+
+    regEntry.name = "test";
+    regEntry.subsystem = 5;
+    regEntry.actionFlags = 0xC000;
+    regEntry.src.type = 0xBD;
+    regEntry.src.reasonCode = 0x1234;
+
+    std::vector<std::string> additionalData{"KEY1=VALUE1"};
+    AdditionalData ad{additionalData};
+    NiceMock<MockDataInterface> dataIface;
+    PelFFDC ffdc;
+
+    std::vector<uint8_t> customData{1, 2, 3, 4, 5, 6, 7, 8};
+
+    // This will be trimmed when added
+    std::vector<uint8_t> hugeCustomData(17000, 0x42);
+
+    ffdc.emplace_back(std::move(getJSONFFDC(dir)));
+    ffdc.emplace_back(std::move(getCBORFFDC(dir)));
+    ffdc.emplace_back(std::move(getTextFFDC(dir)));
+    ffdc.emplace_back(std::move(getCustomFFDC(dir, customData)));
+    ffdc.emplace_back(std::move(getCustomFFDC(dir, hugeCustomData)));
+
+    PEL pel{regEntry, 42,   timestamp, phosphor::logging::Entry::Level::Error,
+            ad,       ffdc, dataIface};
+
+    EXPECT_TRUE(pel.valid());
+
+    // Clipped to the max
+    EXPECT_EQ(pel.size(), 16384);
+
+    // Check for the FFDC sections
+    size_t udCount = 0;
+    Section* ud = nullptr;
+
+    for (const auto& section : pel.optionalSections())
+    {
+        if (section->header().id == static_cast<uint16_t>(SectionID::userData))
+        {
+            udCount++;
+            ud = section.get();
+        }
+    }
+
+    EXPECT_EQ(udCount, 7); // AD section, sysInfo, 5 ffdc sections
+
+    // Check the last section was trimmed to
+    // something a bit less that 17000.
+    EXPECT_GT(ud->header().size, 14000);
+    EXPECT_LT(ud->header().size, 16000);
+
+    fs::remove_all(dir);
+}
