diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index ba5165766b2b..edc2b17f5d3a 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1136,6 +1136,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"zcf", "f",		check_implicit_always},
   {"zfa", "f",		check_implicit_always},
   {"d", "f",		check_implicit_always},
+  {"zfbfmin", "f",	check_implicit_always},
   {"zfh", "zfhmin",	check_implicit_always},
   {"zfhmin", "f",	check_implicit_always},
   {"f", "zicsr",	check_implicit_always},
@@ -1254,6 +1255,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfa",		ISA_SPEC_CLASS_DRAFT,		0, 1,  0 },
+  {"zfbfmin",		ISA_SPEC_CLASS_DRAFT,		0, 8,  0 },
   {"zfh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfhmin",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
@@ -2422,11 +2424,14 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
     case INSN_CLASS_Q_INX:
       return (riscv_subset_supports (rps, "q")
 	      || riscv_subset_supports (rps, "zqinx"));
+    case INSN_CLASS_ZFBFMIN:
+      return riscv_subset_supports (rps, "zfbfmin");
     case INSN_CLASS_ZFH_INX:
       return (riscv_subset_supports (rps, "zfh")
 	      || riscv_subset_supports (rps, "zhinx"));
     case INSN_CLASS_ZFHMIN:
-      return riscv_subset_supports (rps, "zfhmin");
+      return (riscv_subset_supports (rps, "zfhmin")
+	      || riscv_subset_supports (rps, "zfbfmin"));
     case INSN_CLASS_ZFHMIN_INX:
       return (riscv_subset_supports (rps, "zfhmin")
 	      || riscv_subset_supports (rps, "zhinxmin"));
@@ -2625,10 +2630,12 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return _("d' or `zdinx");
     case INSN_CLASS_Q_INX:
       return _("q' or `zqinx");
+    case INSN_CLASS_ZFBFMIN:
+      return "zfbfmin";
     case INSN_CLASS_ZFH_INX:
       return _("zfh' or `zhinx");
     case INSN_CLASS_ZFHMIN:
-      return "zfhmin";
+      return _("zfhmin' or `zfbfmin");
     case INSN_CLASS_ZFHMIN_INX:
       return _("zfhmin' or `zhinxmin");
     case INSN_CLASS_ZFHMIN_AND_D_INX:
diff --git a/gas/testsuite/gas/riscv/zfbfmin.d b/gas/testsuite/gas/riscv/zfbfmin.d
new file mode 100644
index 000000000000..28675457a0a9
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfbfmin.d
@@ -0,0 +1,15 @@
+#as: -march=rv32i_zfbfmin
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+4485f553[ 	]+fcvt\.bf16\.s[ 	]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+44859553[ 	]+fcvt\.bf16\.s[ 	]+fa0,fa1,rtz
+[ 	]+[0-9a-f]+:[ 	]+40658553[ 	]+fcvt\.s\.bf16[ 	]+fa0,fa1
+[ 	]+[0-9a-f]+:[ 	]+00059507[ 	]+flh[ 	]+fa0,0\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+00a59027[ 	]+fsh[ 	]+fa0,0\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e4058553[ 	]+fmv\.x\.h[ 	]+a0,fa1
+[ 	]+[0-9a-f]+:[ 	]+f4058553[ 	]+fmv\.h\.x[ 	]+fa0,a1
diff --git a/gas/testsuite/gas/riscv/zfbfmin.s b/gas/testsuite/gas/riscv/zfbfmin.s
new file mode 100644
index 000000000000..a0670a33ce69
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zfbfmin.s
@@ -0,0 +1,10 @@
+target:
+	# Zfbfmin only instructions
+	fcvt.bf16.s	fa0, fa1
+	fcvt.bf16.s	fa0, fa1, rtz
+	fcvt.s.bf16	fa0, fa1
+	# Instructions shared with Zfhmin
+	flh		fa0, 0(a1)
+	fsh		fa0, 0(a1)
+	fmv.x.h		a0, fa1
+	fmv.h.x		fa0, a1
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 53f5f2005085..864faddcc6a5 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2121,6 +2121,11 @@
 #define MASK_VDOTUVV  0xfc00707f
 #define MATCH_VFDOTVV  0xe4001057
 #define MASK_VFDOTVV  0xfc00707f
+/* Zfbfmin instructions.  */
+#define MATCH_FCVT_BF16_S 0x44800053
+#define MASK_FCVT_BF16_S 0xfff0007f
+#define MATCH_FCVT_S_BF16 0x40600053
+#define MASK_FCVT_S_BF16 0xfff0007f
 /* Zvbb instructions.  */
 #define MATCH_VANDN_VV 0x4000057
 #define MASK_VANDN_VV 0xfc00707f
@@ -3344,6 +3349,9 @@ DECLARE_INSN(czero_nez, MATCH_CZERO_NEZ, MASK_CZERO_NEZ)
 /* Zawrs instructions.  */
 DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO)
 DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO)
+/* Zfbfmin instructions.  */
+DECLARE_INSN(fcvt_bf16_s, MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S)
+DECLARE_INSN(fcvt_s_bf16, MATCH_FCVT_S_BF16, MASK_FCVT_S_BF16)
 /* Zvbb instructions.  */
 DECLARE_INSN(vandn_vv, MATCH_VANDN_VV, MASK_VANDN_VV)
 DECLARE_INSN(vandn_vx, MATCH_VANDN_VX, MASK_VANDN_VX)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 808f36573030..4db29287ebe9 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -398,6 +398,7 @@ enum riscv_insn_class
   INSN_CLASS_F_INX,
   INSN_CLASS_D_INX,
   INSN_CLASS_Q_INX,
+  INSN_CLASS_ZFBFMIN,
   INSN_CLASS_ZFH_INX,
   INSN_CLASS_ZFHMIN,
   INSN_CLASS_ZFHMIN_INX,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 6a854736fec0..5c9809c3c4f7 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -974,6 +974,11 @@ const struct riscv_opcode riscv_opcodes[] =
 {"wrs.nto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_NTO, MASK_WRS_NTO, match_opcode, 0 },
 {"wrs.sto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_STO, MASK_WRS_STO, match_opcode, 0 },
 
+/* Zfbfmin instructions.  */
+{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN,     "D,S",   MATCH_FCVT_BF16_S|MASK_RM, MASK_FCVT_BF16_S|MASK_RM, match_opcode, 0 },
+{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN,     "D,S,m", MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S, match_opcode, 0 },
+{"fcvt.s.bf16", 0, INSN_CLASS_ZFBFMIN,     "D,S",   MATCH_FCVT_S_BF16, MASK_FCVT_S_BF16|MASK_RM, match_opcode, 0 },
+
 /* Zfa instructions.  */
 {"fli.s",       0, INSN_CLASS_ZFA,         "D,Wfv", MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 },
 {"fli.d",       0, INSN_CLASS_D_AND_ZFA,   "D,Wfv", MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 },
