diff --git a/oem/ibm/libpldmresponder/file_io.cpp b/oem/ibm/libpldmresponder/file_io.cpp
index a3a81b4..24997fb 100644
--- a/oem/ibm/libpldmresponder/file_io.cpp
+++ b/oem/ibm/libpldmresponder/file_io.cpp
@@ -34,6 +34,8 @@
                     std::move(readFileIntoMemory));
     registerHandler(PLDM_OEM, PLDM_WRITE_FILE_FROM_MEMORY,
                     std::move(writeFileFromMemory));
+    registerHandler(PLDM_OEM, PLDM_READ_FILE, std::move(readFile));
+    registerHandler(PLDM_OEM, PLDM_WRITE_FILE, std::move(writeFile));
 }
 
 } // namespace oem_ibm
@@ -366,5 +368,160 @@
     return response;
 }
 
+Response readFile(const pldm_msg* request, size_t payloadLength)
+{
+    uint32_t fileHandle = 0;
+    uint32_t offset = 0;
+    uint32_t length = 0;
+
+    Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+    if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
+    {
+        encode_read_file_resp(request->hdr.instance_id,
+                              PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
+        return response;
+    }
+
+    auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
+                                   &length);
+
+    if (rc)
+    {
+        encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
+        return response;
+    }
+
+    using namespace pldm::filetable;
+    auto& table = buildFileTable(FILE_TABLE_JSON);
+    FileEntry value{};
+
+    try
+    {
+        value = table.at(fileHandle);
+    }
+    catch (std::exception& e)
+    {
+        log<level::ERR>("File handle does not exist in the file table",
+                        entry("HANDLE=%d", fileHandle));
+        encode_read_file_resp(request->hdr.instance_id,
+                              PLDM_INVALID_FILE_HANDLE, length, responsePtr);
+        return response;
+    }
+
+    if (!fs::exists(value.fsPath))
+    {
+        log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
+        encode_read_file_resp(request->hdr.instance_id,
+                              PLDM_INVALID_FILE_HANDLE, length, responsePtr);
+        return response;
+    }
+
+    auto fileSize = fs::file_size(value.fsPath);
+    if (offset >= fileSize)
+    {
+        log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
+                        entry("FILE_SIZE=%d", fileSize));
+        encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
+                              length, responsePtr);
+        return response;
+    }
+
+    if (offset + length > fileSize)
+    {
+        length = fileSize - offset;
+    }
+
+    response.resize(response.size() + length);
+    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    auto fileDataPos = reinterpret_cast<char*>(responsePtr);
+    fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
+
+    std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
+    stream.seekg(offset);
+    stream.read(fileDataPos, length);
+
+    encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
+                          responsePtr);
+
+    return response;
+}
+
+Response writeFile(const pldm_msg* request, size_t payloadLength)
+{
+    uint32_t fileHandle = 0;
+    uint32_t offset = 0;
+    uint32_t length = 0;
+    size_t fileDataOffset = 0;
+
+    Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+    if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
+    {
+        encode_write_file_resp(request->hdr.instance_id,
+                               PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
+        return response;
+    }
+
+    auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
+                                    &offset, &length, &fileDataOffset);
+
+    if (rc)
+    {
+        encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
+        return response;
+    }
+
+    using namespace pldm::filetable;
+    auto& table = buildFileTable(FILE_TABLE_JSON);
+    FileEntry value{};
+
+    try
+    {
+        value = table.at(fileHandle);
+    }
+    catch (std::exception& e)
+    {
+        log<level::ERR>("File handle does not exist in the file table",
+                        entry("HANDLE=%d", fileHandle));
+        encode_write_file_resp(request->hdr.instance_id,
+                               PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
+        return response;
+    }
+
+    if (!fs::exists(value.fsPath))
+    {
+        log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
+        encode_write_file_resp(request->hdr.instance_id,
+                               PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
+        return response;
+    }
+
+    auto fileSize = fs::file_size(value.fsPath);
+    if (offset >= fileSize)
+    {
+        log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
+                        entry("FILE_SIZE=%d", fileSize));
+        encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
+                               0, responsePtr);
+        return response;
+    }
+
+    auto fileDataPos =
+        reinterpret_cast<const char*>(request->payload) + fileDataOffset;
+
+    std::ofstream stream(value.fsPath,
+                         std::ios::in | std::ios::out | std::ios::binary);
+    stream.seekp(offset);
+    stream.write(fileDataPos, length);
+
+    encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
+                           responsePtr);
+
+    return response;
+}
+
 } // namespace responder
 } // namespace pldm
diff --git a/oem/ibm/libpldmresponder/file_io.hpp b/oem/ibm/libpldmresponder/file_io.hpp
index 30236ce..0ee4ed6 100644
--- a/oem/ibm/libpldmresponder/file_io.hpp
+++ b/oem/ibm/libpldmresponder/file_io.hpp
@@ -147,5 +147,23 @@
  *  @return PLDM response message
  */
 Response getFileTable(const pldm_msg* request, size_t payloadLength);
+
+/** @brief Handler for readFile command
+ *
+ *  @param[in] request - PLDM request msg
+ *  @param[in] payloadLength - length of the message payload
+ *
+ *  @return PLDM response message
+ */
+Response readFile(const pldm_msg* request, size_t payloadLength);
+
+/** @brief Handler for writeFile command
+ *
+ *  @param[in] request - PLDM request msg
+ *  @param[in] payloadLength - length of the message payload
+ *
+ *  @return PLDM response message
+ */
+Response writeFile(const pldm_msg* request, size_t payloadLength);
 } // namespace responder
 } // namespace pldm
diff --git a/oem/ibm/test/libpldmresponder_fileio_test.cpp b/oem/ibm/test/libpldmresponder_fileio_test.cpp
index d44854f..c132895 100644
--- a/oem/ibm/test/libpldmresponder_fileio_test.cpp
+++ b/oem/ibm/test/libpldmresponder_fileio_test.cpp
@@ -560,3 +560,185 @@
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE);
 }
+
+TEST_F(TestFileTable, ReadFileBadPath)
+{
+    uint32_t fileHandle = 1;
+    uint32_t offset = 0;
+    uint32_t length = 0x4;
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES>
+        requestMsg{};
+    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
+    auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() +
+                                                         sizeof(pldm_msg_hdr));
+
+    request->file_handle = fileHandle;
+    request->offset = offset;
+    request->length = length;
+
+    using namespace pldm::filetable;
+    // Initialise the file table with 2 valid file handles 0 & 1.
+    auto& table = buildFileTable(fileTableConfig.c_str());
+
+    // Invalid payload length
+    auto response = readFile(requestMsgPtr, 0);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
+
+    // Data out of range. File size is 1024, offset = 1024 is invalid.
+    request->offset = 1024;
+
+    response = readFile(requestMsgPtr, payload_length);
+    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
+
+    // Invalid file handle
+    request->file_handle = 2;
+
+    response = readFile(requestMsgPtr, payload_length);
+    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
+
+    table.clear();
+}
+
+TEST_F(TestFileTable, ReadFileGoodPath)
+{
+    uint32_t fileHandle = 0;
+    uint32_t offset = 0;
+    uint32_t length = 0x4;
+
+    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES>
+        requestMsg{};
+    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
+    auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() +
+                                                         sizeof(pldm_msg_hdr));
+
+    request->file_handle = fileHandle;
+    request->offset = offset;
+    request->length = length;
+
+    using namespace pldm::filetable;
+    // Initialise the file table with 2 valid file handles 0 & 1.
+    auto& table = buildFileTable(fileTableConfig.c_str());
+    FileEntry value{};
+    value = table.at(fileHandle);
+
+    std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
+    stream.seekg(offset);
+    std::vector<char> buffer(length);
+    stream.read(buffer.data(), length);
+
+    auto responseMsg = readFile(requestMsgPtr, payload_length);
+    auto response = reinterpret_cast<pldm_read_file_resp*>(
+        responseMsg.data() + sizeof(pldm_msg_hdr));
+    ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
+    ASSERT_EQ(response->length, length);
+    ASSERT_EQ(0, memcmp(response->file_data, buffer.data(), length));
+
+    // Test condition offset + length > fileSize;
+    size_t fileSize = 1024;
+    request->offset = 1023;
+    request->length = 10;
+
+    stream.seekg(request->offset);
+    buffer.resize(fileSize - request->offset);
+    stream.read(buffer.data(), (fileSize - request->offset));
+
+    responseMsg = readFile(requestMsgPtr, payload_length);
+    response = reinterpret_cast<pldm_read_file_resp*>(responseMsg.data() +
+                                                      sizeof(pldm_msg_hdr));
+    ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
+    ASSERT_EQ(response->length, (fileSize - request->offset));
+    ASSERT_EQ(0, memcmp(response->file_data, buffer.data(),
+                        (fileSize - request->offset)));
+
+    table.clear();
+}
+
+TEST_F(TestFileTable, WriteFileBadPath)
+{
+    uint32_t fileHandle = 0;
+    uint32_t offset = 0;
+    uint32_t length = 0x10;
+
+    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+                                    PLDM_WRITE_FILE_REQ_BYTES + length);
+    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
+    auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() +
+                                                          sizeof(pldm_msg_hdr));
+
+    using namespace pldm::filetable;
+    // Initialise the file table with 2 valid file handles 0 & 1.
+    auto& table = buildFileTable(fileTableConfig.c_str());
+
+    request->file_handle = fileHandle;
+    request->offset = offset;
+    request->length = length;
+
+    // Invalid payload length
+    auto response = writeFile(requestMsgPtr, 0);
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
+
+    // Data out of range. File size is 1024, offset = 1024 is invalid.
+    request->offset = 1024;
+
+    response = writeFile(requestMsgPtr, payload_length);
+    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
+
+    // Invalid file handle
+    request->file_handle = 2;
+
+    response = writeFile(requestMsgPtr, payload_length);
+    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+    ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
+
+    table.clear();
+}
+
+TEST_F(TestFileTable, WriteFileGoodPath)
+{
+    uint32_t fileHandle = 1;
+    uint32_t offset = 0;
+    std::array<uint8_t, 4> fileData = {0x41, 0x42, 0x43, 0x44};
+    uint32_t length = fileData.size();
+
+    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+                                    PLDM_WRITE_FILE_REQ_BYTES + length);
+    auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
+    auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() +
+                                                          sizeof(pldm_msg_hdr));
+
+    using namespace pldm::filetable;
+    // Initialise the file table with 2 valid file handles 0 & 1.
+    auto& table = buildFileTable(fileTableConfig.c_str());
+    FileEntry value{};
+    value = table.at(fileHandle);
+
+    request->file_handle = fileHandle;
+    request->offset = offset;
+    request->length = length;
+    memcpy(request->file_data, fileData.data(), fileData.size());
+
+    auto responseMsg = writeFile(requestMsgPtr, payload_length);
+    auto response = reinterpret_cast<pldm_read_file_resp*>(
+        responseMsg.data() + sizeof(pldm_msg_hdr));
+
+    std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
+    stream.seekg(offset);
+    std::vector<char> buffer(length);
+    stream.read(buffer.data(), length);
+
+    ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
+    ASSERT_EQ(response->length, length);
+    ASSERT_EQ(0, memcmp(fileData.data(), buffer.data(), length));
+
+    table.clear();
+}
