diff --git a/src/citra_qt/multiplayer/chat_room.cpp b/src/citra_qt/multiplayer/chat_room.cpp
index de25949db..0c1a2310c 100644
--- a/src/citra_qt/multiplayer/chat_room.cpp
+++ b/src/citra_qt/multiplayer/chat_room.cpp
@@ -8,6 +8,8 @@
 #include <QImage>
 #include <QList>
 #include <QLocale>
+#include <QMenu>
+#include <QMessageBox>
 #include <QMetaType>
 #include <QTime>
 #include <QtConcurrent/QtConcurrentRun>
@@ -77,6 +79,7 @@ ChatRoom::ChatRoom(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::C
 
     player_list = new QStandardItemModel(ui->player_view);
     ui->player_view->setModel(player_list);
+    ui->player_view->setContextMenuPolicy(Qt::CustomContextMenu);
     player_list->insertColumns(0, COLUMN_COUNT);
     player_list->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
     player_list->setHeaderData(COLUMN_GAME, Qt::Horizontal, tr("Game"));
@@ -98,6 +101,8 @@ ChatRoom::ChatRoom(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::C
     }
 
     // Connect all the widgets to the appropriate events
+    connect(ui->player_view, &QTreeView::customContextMenuRequested, this,
+            &ChatRoom::PopupContextMenu);
     connect(ui->chat_message, &QLineEdit::returnPressed, ui->send_message, &QPushButton::pressed);
     connect(ui->chat_message, &QLineEdit::textChanged, this, &::ChatRoom::OnChatTextChanged);
     connect(ui->send_message, &QPushButton::pressed, this, &ChatRoom::OnSendChat);
@@ -107,6 +112,7 @@ ChatRoom::~ChatRoom() = default;
 
 void ChatRoom::Clear() {
     ui->chat_history->clear();
+    block_list.clear();
 }
 
 void ChatRoom::AppendStatusMessage(const QString& msg) {
@@ -153,6 +159,11 @@ void ChatRoom::OnChatReceive(const Network::ChatEntry& chat) {
             LOG_INFO(Network, "Chat message received from unknown player. Ignoring it.");
             return;
         }
+        if (block_list.count(chat.nickname)) {
+            LOG_INFO(Network, "Chat message received from blocked player {}. Ignoring it.",
+                     chat.nickname);
+            return;
+        }
         auto player = std::distance(members.begin(), it);
         ChatMessage m(chat);
         AppendChatMessage(m.GetPlayerChatMessage(player));
@@ -209,3 +220,39 @@ void ChatRoom::OnChatTextChanged() {
     if (ui->chat_message->text().length() > Network::MaxMessageSize)
         ui->chat_message->setText(ui->chat_message->text().left(Network::MaxMessageSize));
 }
+
+void ChatRoom::PopupContextMenu(const QPoint& menu_location) {
+    QModelIndex item = ui->player_view->indexAt(menu_location);
+    if (!item.isValid())
+        return;
+
+    std::string nickname = player_list->item(item.row())->text().toStdString();
+    if (auto room = Network::GetRoomMember().lock()) {
+        // You can't block yourself
+        if (nickname == room->GetNickname())
+            return;
+    }
+
+    QMenu context_menu;
+    QAction* block_action = context_menu.addAction(tr("Block Player"));
+
+    block_action->setCheckable(true);
+    block_action->setChecked(block_list.count(nickname) > 0);
+
+    connect(block_action, &QAction::triggered, [this, nickname] {
+        if (block_list.count(nickname)) {
+            block_list.erase(nickname);
+        } else {
+            QMessageBox::StandardButton result = QMessageBox::question(
+                this, tr("Block Player"),
+                tr("When you block a player, you will no longer receive chat messages from "
+                   "them.<br><br>Are you sure you would like to block %1?")
+                    .arg(QString::fromStdString(nickname)),
+                QMessageBox::Yes | QMessageBox::No);
+            if (result == QMessageBox::Yes)
+                block_list.emplace(nickname);
+        }
+    });
+
+    context_menu.exec(ui->player_view->viewport()->mapToGlobal(menu_location));
+}
diff --git a/src/citra_qt/multiplayer/chat_room.h b/src/citra_qt/multiplayer/chat_room.h
index 4604c3395..284f02bca 100644
--- a/src/citra_qt/multiplayer/chat_room.h
+++ b/src/citra_qt/multiplayer/chat_room.h
@@ -5,6 +5,7 @@
 #pragma once
 
 #include <memory>
+#include <unordered_set>
 #include <QDialog>
 #include <QSortFilterProxyModel>
 #include <QStandardItemModel>
@@ -39,6 +40,7 @@ public slots:
     void OnChatReceive(const Network::ChatEntry&);
     void OnSendChat();
     void OnChatTextChanged();
+    void PopupContextMenu(const QPoint& menu_location);
     void Disable();
     void Enable();
 
@@ -51,6 +53,7 @@ private:
     bool ValidateMessage(const std::string&);
     QStandardItemModel* player_list;
     std::unique_ptr<Ui::ChatRoom> ui;
+    std::unordered_set<std::string> block_list;
 };
 
 Q_DECLARE_METATYPE(Network::ChatEntry);