diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index bbd681eaeb615c6c034f2281b7f967ab9aee8828..9e585b082a8de46816badaf59a281b30ca952bb2 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <QApplication>
+#include <QDir>
 #include <QFileInfo>
 #include <QHeaderView>
 #include <QKeyEvent>
@@ -264,8 +265,17 @@ void GameList::ValidateEntry(const QModelIndex& item) {
     if (file_path.isEmpty())
         return;
     std::string std_file_path(file_path.toStdString());
-    if (!FileUtil::Exists(std_file_path) || FileUtil::IsDirectory(std_file_path))
+    if (!FileUtil::Exists(std_file_path))
         return;
+    if (FileUtil::IsDirectory(std_file_path)) {
+        QDir dir(std_file_path.c_str());
+        QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
+        if (matching_main.size() == 1) {
+            emit GameChosen(dir.path() + DIR_SEP + matching_main[0]);
+        }
+        return;
+    }
+
     // Users usually want to run a diffrent game after closing one
     search_field->clear();
     emit GameChosen(file_path);
@@ -363,6 +373,19 @@ static bool HasSupportedFileExtension(const std::string& file_name) {
     return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive);
 }
 
+static bool IsExtractedNCAMain(const std::string& file_name) {
+    return QFileInfo(file_name.c_str()).fileName() == "main";
+}
+
+static QString FormatGameName(const std::string& physical_name) {
+    QFileInfo file_info(physical_name.c_str());
+    if (IsExtractedNCAMain(physical_name)) {
+        return file_info.dir().path();
+    } else {
+        return QString::fromStdString(physical_name);
+    }
+}
+
 void GameList::RefreshGameDirectory() {
     if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
         NGLOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
@@ -380,7 +403,8 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
             return false; // Breaks the callback loop.
 
         bool is_dir = FileUtil::IsDirectory(physical_name);
-        if (!is_dir && HasSupportedFileExtension(physical_name)) {
+        if (!is_dir &&
+            (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) {
             std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name);
             if (!loader)
                 return true;
@@ -392,7 +416,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
             loader->ReadProgramId(program_id);
 
             emit EntryReady({
-                new GameListItemPath(QString::fromStdString(physical_name), smdh, program_id),
+                new GameListItemPath(FormatGameName(physical_name), smdh, program_id),
                 new GameListItem(
                     QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
                 new GameListItemSize(FileUtil::GetSize(physical_name)),
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index aa9028399b0f9cd2005b2a8a94c64092ead3e0f8..97be548d730cc58dfd6f4a1f649565cbee328e5e 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -13,6 +13,7 @@
 #include <QMessageBox>
 #include <QtGui>
 #include <QtWidgets>
+#include "common/common_paths.h"
 #include "common/logging/backend.h"
 #include "common/logging/filter.h"
 #include "common/logging/log.h"
@@ -278,6 +279,7 @@ void GMainWindow::ConnectWidgetEvents() {
 void GMainWindow::ConnectMenuEvents() {
     // File
     connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile);
+    connect(ui.action_Load_Folder, &QAction::triggered, this, &GMainWindow::OnMenuLoadFolder);
     connect(ui.action_Select_Game_List_Root, &QAction::triggered, this,
             &GMainWindow::OnMenuSelectGameListRoot);
     connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close);
@@ -550,6 +552,8 @@ void GMainWindow::OnMenuLoadFile() {
     for (const auto& piece : game_list->supported_file_extensions)
         extensions += "*." + piece + " ";
 
+    extensions += "main ";
+
     QString file_filter = tr("Switch Executable") + " (" + extensions + ")";
     file_filter += ";;" + tr("All Files (*.*)");
 
@@ -562,6 +566,18 @@ void GMainWindow::OnMenuLoadFile() {
     }
 }
 
+void GMainWindow::OnMenuLoadFolder() {
+    QDir dir = QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory"));
+
+    QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
+    if (matching_main.size() == 1) {
+        BootGame(dir.path() + DIR_SEP + matching_main[0]);
+    } else {
+        QMessageBox::warning(this, tr("Invalid Directory Selected"),
+                             tr("The directory you have selected does not contain a 'main' file."));
+    }
+}
+
 void GMainWindow::OnMenuSelectGameListRoot() {
     QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory"));
     if (!dir_path.isEmpty()) {
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 3e29d5fc4c4bea2aaba4a9b4d1234b748b2f3479..074bba3f9c9edfa73ff73c8c273153d18ebdf051 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -123,6 +123,7 @@ private slots:
     void OnGameListLoadFile(QString game_path);
     void OnGameListOpenSaveFolder(u64 program_id);
     void OnMenuLoadFile();
+    void OnMenuLoadFolder();
     /// Called whenever a user selects the "File->Select Game List Root" menu item
     void OnMenuSelectGameListRoot();
     void OnMenuRecentFile();
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui
index 0fcd93cc25d39ee9da1104d8258b31af2f544717..22c4cad08c374e66a92c1d4fdd23744bf5f28b01 100644
--- a/src/yuzu/main.ui
+++ b/src/yuzu/main.ui
@@ -58,6 +58,7 @@
      </property>
     </widget>
     <addaction name="action_Load_File"/>
+    <addaction name="action_Load_Folder"/>
     <addaction name="separator"/>
     <addaction name="action_Select_Game_List_Root"/>
     <addaction name="menu_recent_files"/>
@@ -106,6 +107,11 @@
     <string>Load File...</string>
    </property>
   </action>
+  <action name="action_Load_Folder">
+   <property name="text">
+    <string>Load Folder...</string>
+   </property>
+  </action>
   <action name="action_Load_Symbol_Map">
    <property name="text">
     <string>Load Symbol Map...</string>