diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 34b44fce1..079a39a7d 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -18,6 +18,7 @@
 #include "core/hle/kernel/errors.h"
 #include "core/hle/kernel/event.h"
 #include "core/hle/kernel/handle_table.h"
+#include "core/hle/kernel/ipc.h"
 #include "core/hle/kernel/memory.h"
 #include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/process.h"
@@ -453,6 +454,33 @@ static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 hand
     }
 }
 
+static ResultCode ReceiveIPCRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session,
+                                    Kernel::SharedPtr<Kernel::Thread> thread) {
+    if (server_session->parent->client == nullptr) {
+        return Kernel::ERR_SESSION_CLOSED_BY_REMOTE;
+    }
+
+    VAddr target_address = thread->GetCommandBufferAddress();
+    VAddr source_address = server_session->currently_handling->GetCommandBufferAddress();
+
+    ResultCode translation_result = Kernel::TranslateCommandBuffer(
+        server_session->currently_handling, thread, source_address, target_address);
+
+    // If a translation error occurred, immediately resume the client thread.
+    if (translation_result.IsError()) {
+        // Set the output of SendSyncRequest in the client thread to the translation output.
+        server_session->currently_handling->SetWaitSynchronizationResult(translation_result);
+
+        server_session->currently_handling->ResumeFromWait();
+        server_session->currently_handling = nullptr;
+
+        // TODO(Subv): This path should try to wait again on the same objects.
+        ASSERT_MSG(false, "ReplyAndReceive translation error behavior unimplemented");
+    }
+
+    return translation_result;
+}
+
 /// In a single operation, sends a IPC reply and waits for a new request.
 static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count,
                                   Kernel::Handle reply_target) {
@@ -495,7 +523,15 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_
             return Kernel::ERR_SESSION_CLOSED_BY_REMOTE;
         }
 
-        // TODO(Subv): Perform IPC translation from the current thread to request_thread.
+        VAddr source_address = Kernel::GetCurrentThread()->GetCommandBufferAddress();
+        VAddr target_address = request_thread->GetCommandBufferAddress();
+
+        ResultCode translation_result = Kernel::TranslateCommandBuffer(
+            Kernel::GetCurrentThread(), request_thread, source_address, target_address);
+
+        // Note: The real kernel seems to always panic if the Server->Client buffer translation
+        // fails for whatever reason.
+        ASSERT(translation_result.IsSuccess());
 
         // Note: The scheduler is not invoked here.
         request_thread->ResumeFromWait();
@@ -524,14 +560,11 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_
         object->Acquire(thread);
         *index = static_cast<s32>(std::distance(objects.begin(), itr));
 
-        if (object->GetHandleType() == Kernel::HandleType::ServerSession) {
-            auto server_session = static_cast<Kernel::ServerSession*>(object);
-            if (server_session->parent->client == nullptr)
-                return Kernel::ERR_SESSION_CLOSED_BY_REMOTE;
+        if (object->GetHandleType() != Kernel::HandleType::ServerSession)
+            return RESULT_SUCCESS;
 
-            // TODO(Subv): Perform IPC translation from the ServerSession to the current thread.
-        }
-        return RESULT_SUCCESS;
+        auto server_session = static_cast<Kernel::ServerSession*>(object);
+        return ReceiveIPCRequest(server_session, Kernel::GetCurrentThread());
     }
 
     // No objects were ready to be acquired, prepare to suspend the thread.
@@ -554,10 +587,15 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_
         ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY);
         ASSERT(reason == ThreadWakeupReason::Signal);
 
-        thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
-        thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get()));
+        ResultCode result = RESULT_SUCCESS;
 
-        // TODO(Subv): Perform IPC translation upon wakeup.
+        if (object->GetHandleType() == Kernel::HandleType::ServerSession) {
+            auto server_session = Kernel::DynamicObjectCast<Kernel::ServerSession>(object);
+            result = ReceiveIPCRequest(server_session, thread);
+        }
+
+        thread->SetWaitSynchronizationResult(result);
+        thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get()));
     };
 
     Core::System::GetInstance().PrepareReschedule();