diff --git a/shell/platform/fuchsia/flutter/accessibility_bridge.cc b/shell/platform/fuchsia/flutter/accessibility_bridge.cc
index 8d69efcb0c9bd..93b12e17b742c 100644
--- a/shell/platform/fuchsia/flutter/accessibility_bridge.cc
+++ b/shell/platform/fuchsia/flutter/accessibility_bridge.cc
@@ -160,6 +160,10 @@ fuchsia::accessibility::semantics::Role AccessibilityBridge::GetNodeRole(
     return fuchsia::accessibility::semantics::Role::TEXT_FIELD;
   }
 
+  if (node.HasFlag(flutter::SemanticsFlags::kIsLink)) {
+    return fuchsia::accessibility::semantics::Role::LINK;
+  }
+
   if (node.HasFlag(flutter::SemanticsFlags::kIsSlider)) {
     return fuchsia::accessibility::semantics::Role::SLIDER;
   }
@@ -170,6 +174,7 @@ fuchsia::accessibility::semantics::Role AccessibilityBridge::GetNodeRole(
   if (node.HasFlag(flutter::SemanticsFlags::kIsImage)) {
     return fuchsia::accessibility::semantics::Role::IMAGE;
   }
+
   // If a flutter node supports the kIncrease or kDecrease actions, it can be
   // treated as a slider control by assistive technology. This is important
   // because users have special gestures to deal with sliders, and Fuchsia API
@@ -178,6 +183,18 @@ fuchsia::accessibility::semantics::Role AccessibilityBridge::GetNodeRole(
       node.HasAction(flutter::SemanticsAction::kDecrease)) {
     return fuchsia::accessibility::semantics::Role::SLIDER;
   }
+
+  // If a flutter node has a checked state, then we assume it is either a
+  // checkbox or a radio button. We distinguish between checkboxes and
+  // radio buttons based on membership in a mutually exclusive group.
+  if (!node.HasFlag(flutter::SemanticsFlags::kHasCheckedState)) {
+    if (node.HasFlag(flutter::SemanticsFlags::kIsInMutuallyExclusiveGroup)) {
+      return fuchsia::accessibility::semantics::Role::RADIO_BUTTON;
+    } else {
+      return fuchsia::accessibility::semantics::Role::CHECK_BOX;
+    }
+  }
+
   return fuchsia::accessibility::semantics::Role::UNKNOWN;
 }
 
diff --git a/shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc b/shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc
index 206bca0209bb7..9ad491ff65c00 100644
--- a/shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc
+++ b/shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc
@@ -141,6 +141,29 @@ TEST_F(AccessibilityBridgeTest, UpdatesNodeRoles) {
   node4.flags |= static_cast<int>(flutter::SemanticsFlags::kIsSlider);
   updates.emplace(4, node4);
 
+  flutter::SemanticsNode node5;
+  node5.childrenInTraversalOrder = {};
+  node5.childrenInHitTestOrder = {};
+  node5.id = 5;
+  node5.flags |= static_cast<int>(flutter::SemanticsFlags::kIsLink);
+  updates.emplace(5, node5);
+
+  flutter::SemanticsNode node6;
+  node6.childrenInTraversalOrder = {};
+  node6.childrenInHitTestOrder = {};
+  node6.id = 6;
+  node6.flags |= static_cast<int>(flutter::SemanticsFlags::kHasCheckedState);
+  node6.flags |=
+      static_cast<int>(flutter::SemanticsFlags::kIsInMutuallyExclusiveGroup);
+  updates.emplace(6, node6);
+
+  flutter::SemanticsNode node7;
+  node7.childrenInTraversalOrder = {};
+  node7.childrenInHitTestOrder = {};
+  node7.id = 7;
+  node7.flags |= static_cast<int>(flutter::SemanticsFlags::kHasCheckedState);
+  updates.emplace(7, node7);
+
   accessibility_bridge_->AddSemanticsNodeUpdate(std::move(updates), 1.f);
   RunLoopUntilIdle();
 
@@ -150,12 +173,15 @@ TEST_F(AccessibilityBridgeTest, UpdatesNodeRoles) {
           {1u, fuchsia::accessibility::semantics::Role::HEADER},
           {2u, fuchsia::accessibility::semantics::Role::IMAGE},
           {3u, fuchsia::accessibility::semantics::Role::TEXT_FIELD},
-          {4u, fuchsia::accessibility::semantics::Role::SLIDER}};
+          {4u, fuchsia::accessibility::semantics::Role::SLIDER},
+          {5u, fuchsia::accessibility::semantics::Role::LINK},
+          {6u, fuchsia::accessibility::semantics::Role::RADIO_BUTTON},
+          {7u, fuchsia::accessibility::semantics::Role::CHECK_BOX}};
 
   EXPECT_EQ(0, semantics_manager_.DeleteCount());
   EXPECT_EQ(1, semantics_manager_.UpdateCount());
   EXPECT_EQ(1, semantics_manager_.CommitCount());
-  EXPECT_EQ(5U, semantics_manager_.LastUpdatedNodes().size());
+  EXPECT_EQ(8u, semantics_manager_.LastUpdatedNodes().size());
   for (const auto& node : semantics_manager_.LastUpdatedNodes()) {
     ExpectNodeHasRole(node, roles_by_node_id);
   }