diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 4abbf8d694..09fcc0d03e 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1383,7 +1383,7 @@ fn main() {
     for e in rcc_registers.ir.enums {
         fn is_rcc_name(e: &str) -> bool {
             match e {
-                "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true,
+                "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" | "Prediv1" | "Prediv2" => true,
                 "Timpre" | "Pllrclkpre" => false,
                 e if e.ends_with("pre") || e.ends_with("pres") || e.ends_with("div") || e.ends_with("mul") => true,
                 _ => false,
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs
index 57c5cd5b2e..13b0ae38e3 100644
--- a/embassy-stm32/src/rcc/f013.rs
+++ b/embassy-stm32/src/rcc/f013.rs
@@ -4,11 +4,13 @@ pub use crate::pac::rcc::vals::Adcpre as ADCPrescaler;
 #[cfg(stm32f3)]
 pub use crate::pac::rcc::vals::Adcpres as AdcPllPrescaler;
 use crate::pac::rcc::vals::Pllsrc;
-#[cfg(stm32f1)]
+#[cfg(all(stm32f1, not(stm32f107)))]
 pub use crate::pac::rcc::vals::Pllxtpre as PllPreDiv;
 #[cfg(any(stm32f0, stm32f3))]
 pub use crate::pac::rcc::vals::Prediv as PllPreDiv;
 pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Pllmul as PllMul, Ppre as APBPrescaler, Sw as Sysclk};
+#[cfg(stm32f107)]
+pub use crate::pac::rcc::vals::{I2s2src, Pll2mul as Pll2Mul, Prediv1 as PllPreDiv, Prediv1src, Usbpre as UsbPre};
 use crate::pac::{FLASH, RCC};
 use crate::time::Hertz;
 
@@ -37,6 +39,8 @@ pub enum PllSource {
     HSI,
     #[cfg(rcc_f0v4)]
     HSI48,
+    #[cfg(stm32f107)]
+    PLL2,
 }
 
 #[derive(Clone, Copy)]
@@ -52,6 +56,12 @@ pub struct Pll {
     pub mul: PllMul,
 }
 
+#[cfg(stm32f107)]
+#[derive(Clone, Copy)]
+pub struct Pll2Or3 {
+    pub mul: Pll2Mul,
+}
+
 #[cfg(all(stm32f3, not(rcc_f37)))]
 #[derive(Clone, Copy)]
 pub enum AdcClockSource {
@@ -85,6 +95,12 @@ pub struct Config {
     pub sys: Sysclk,
 
     pub pll: Option<Pll>,
+    #[cfg(stm32f107)]
+    pub pll2: Option<Pll2Or3>,
+    #[cfg(stm32f107)]
+    pub pll3: Option<Pll2Or3>,
+    #[cfg(stm32f107)]
+    pub prediv2: PllPreDiv,
 
     pub ahb_pre: AHBPrescaler,
     pub apb1_pre: APBPrescaler,
@@ -99,6 +115,11 @@ pub struct Config {
     #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
     pub adc34: AdcClockSource,
 
+    #[cfg(stm32f107)]
+    pub i2s2_src: I2s2src,
+    #[cfg(stm32f107)]
+    pub i2s3_src: I2s2src,
+
     /// Per-peripheral kernel clock selection muxes
     pub mux: super::mux::ClockMux,
 
@@ -114,6 +135,14 @@ impl Default for Config {
             hsi48: Some(Default::default()),
             sys: Sysclk::HSI,
             pll: None,
+
+            #[cfg(stm32f107)]
+            pll2: None,
+            #[cfg(stm32f107)]
+            pll3: None,
+            #[cfg(stm32f107)]
+            prediv2: PllPreDiv::DIV1,
+
             ahb_pre: AHBPrescaler::DIV1,
             apb1_pre: APBPrescaler::DIV1,
             #[cfg(not(stm32f0))]
@@ -129,6 +158,11 @@ impl Default for Config {
             #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
             adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
 
+            #[cfg(stm32f107)]
+            i2s2_src: I2s2src::SYS,
+            #[cfg(stm32f107)]
+            i2s3_src: I2s2src::SYS,
+
             mux: Default::default(),
         }
     }
@@ -175,6 +209,28 @@ pub(crate) unsafe fn init(config: Config) {
     #[cfg(not(crs))]
     let hsi48: Option<Hertz> = None;
 
+    // PLL2 and PLL3
+    // Configure this before PLL since PLL2 can be the source for PLL.
+    #[cfg(stm32f107)]
+    {
+        // Common prediv for PLL2 and PLL3
+        RCC.cfgr2().modify(|w| w.set_prediv2(config.prediv2));
+
+        // Configure PLL2
+        if let Some(pll2) = config.pll2 {
+            RCC.cfgr2().modify(|w| w.set_pll2mul(pll2.mul));
+            RCC.cr().modify(|w| w.set_pll2on(true));
+            while !RCC.cr().read().pll2rdy() {}
+        }
+
+        // Configure PLL3
+        if let Some(pll3) = config.pll3 {
+            RCC.cfgr2().modify(|w| w.set_pll3mul(pll3.mul));
+            RCC.cr().modify(|w| w.set_pll3on(true));
+            while !RCC.cr().read().pll3rdy() {}
+        }
+    }
+
     // Enable PLL
     let pll = config.pll.map(|pll| {
         let (src_val, src_freq) = match pll.src {
@@ -187,21 +243,44 @@ pub(crate) unsafe fn init(config: Config) {
                 }
                 (Pllsrc::HSI_DIV2, unwrap!(hsi))
             }
-            PllSource::HSE => (Pllsrc::HSE_DIV_PREDIV, unwrap!(hse)),
+            PllSource::HSE => {
+                #[cfg(stm32f107)]
+                RCC.cfgr2().modify(|w| w.set_prediv1src(Prediv1src::HSE));
+
+                (Pllsrc::HSE_DIV_PREDIV, unwrap!(hse))
+            }
             #[cfg(rcc_f0v4)]
             PllSource::HSI48 => (Pllsrc::HSI48_DIV_PREDIV, unwrap!(hsi48)),
+            #[cfg(stm32f107)]
+            PllSource::PLL2 => {
+                if config.pll2.is_none() {
+                    panic!("if PLL source is PLL2, Config::pll2 must also be set.");
+                }
+                RCC.cfgr2().modify(|w| w.set_prediv1src(Prediv1src::PLL2));
+
+                let pll2 = unwrap!(config.pll2);
+                let in_freq = hse.unwrap() / config.prediv2;
+                let pll2freq = in_freq * pll2.mul;
+
+                (Pllsrc::HSE_DIV_PREDIV, pll2freq)
+            }
         };
         let in_freq = src_freq / pll.prediv;
+
         rcc_assert!(max::PLL_IN.contains(&in_freq));
         let out_freq = in_freq * pll.mul;
         rcc_assert!(max::PLL_OUT.contains(&out_freq));
 
         #[cfg(not(stm32f1))]
         RCC.cfgr2().modify(|w| w.set_prediv(pll.prediv));
+
+        #[cfg(stm32f107)]
+        RCC.cfgr2().modify(|w| w.set_prediv1(pll.prediv));
+
         RCC.cfgr().modify(|w| {
             w.set_pllmul(pll.mul);
             w.set_pllsrc(src_val);
-            #[cfg(stm32f1)]
+            #[cfg(all(stm32f1, not(stm32f107)))]
             w.set_pllxtpre(pll.prediv);
         });
         RCC.cr().modify(|w| w.set_pllon(true));
@@ -213,7 +292,7 @@ pub(crate) unsafe fn init(config: Config) {
     #[cfg(stm32f3)]
     let pll_mul_2 = pll.map(|pll| pll * 2u32);
 
-    #[cfg(any(rcc_f1, rcc_f1cl, stm32f3))]
+    #[cfg(any(rcc_f1, rcc_f1cl, stm32f3, stm32f107))]
     let usb = match pll {
         Some(Hertz(72_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1_5),
         Some(Hertz(48_000_000)) => Some(crate::pac::rcc::vals::Usbpre::DIV1),
@@ -293,6 +372,13 @@ pub(crate) unsafe fn init(config: Config) {
         w.set_adcpre(config.adc_pre);
     });
 
+    // I2S2 and I2S3
+    #[cfg(stm32f107)]
+    {
+        RCC.cfgr2().modify(|w| w.set_i2s2src(config.i2s2_src));
+        RCC.cfgr2().modify(|w| w.set_i2s3src(config.i2s3_src));
+    }
+
     // Wait for the new prescalers to kick in
     // "The clocks are divided with the new prescaler factor from
     //  1 to 16 AHB cycles after write"