diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index 2688a707a7..7c55d9e5cd 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -73,6 +73,58 @@ static void quark_setup_bars(void)
 		       CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN);
 }
 
+static void quark_pcie_early_init(void)
+{
+	u32 pcie_cfg;
+
+	/*
+	 * Step1: Assert PCIe signal PERST#
+	 *
+	 * The CPU interface to the PERST# signal is platform dependent.
+	 * Call the board-specific codes to perform this task.
+	 */
+	board_assert_perst();
+
+	/* Step2: PHY common lane reset */
+	pcie_cfg = msg_port_alt_read(MSG_PORT_SOC_UNIT, PCIE_CFG);
+	pcie_cfg |= PCIE_PHY_LANE_RST;
+	msg_port_alt_write(MSG_PORT_SOC_UNIT, PCIE_CFG, pcie_cfg);
+	/* wait 1 ms for PHY common lane reset */
+	mdelay(1);
+
+	/* Step3: PHY sideband interface reset and controller main reset */
+	pcie_cfg = msg_port_alt_read(MSG_PORT_SOC_UNIT, PCIE_CFG);
+	pcie_cfg |= (PCIE_PHY_SB_RST | PCIE_CTLR_MAIN_RST);
+	msg_port_alt_write(MSG_PORT_SOC_UNIT, PCIE_CFG, pcie_cfg);
+	/* wait 80ms for PLL to lock */
+	mdelay(80);
+
+	/* Step4: Controller sideband interface reset */
+	pcie_cfg = msg_port_alt_read(MSG_PORT_SOC_UNIT, PCIE_CFG);
+	pcie_cfg |= PCIE_CTLR_SB_RST;
+	msg_port_alt_write(MSG_PORT_SOC_UNIT, PCIE_CFG, pcie_cfg);
+	/* wait 20ms for controller sideband interface reset */
+	mdelay(20);
+
+	/* Step5: De-assert PERST# */
+	board_deassert_perst();
+
+	/* Step6: Controller primary interface reset */
+	pcie_cfg = msg_port_alt_read(MSG_PORT_SOC_UNIT, PCIE_CFG);
+	pcie_cfg |= PCIE_CTLR_PRI_RST;
+	msg_port_alt_write(MSG_PORT_SOC_UNIT, PCIE_CFG, pcie_cfg);
+
+	/* Mixer Load Lane 0 */
+	pcie_cfg = msg_port_io_read(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L0);
+	pcie_cfg &= ~((1 << 6) | (1 << 7));
+	msg_port_io_write(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L0, pcie_cfg);
+
+	/* Mixer Load Lane 1 */
+	pcie_cfg = msg_port_io_read(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L1);
+	pcie_cfg &= ~((1 << 6) | (1 << 7));
+	msg_port_io_write(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L1, pcie_cfg);
+}
+
 static void quark_enable_legacy_seg(void)
 {
 	u32 hmisc2;
@@ -106,6 +158,17 @@ int arch_cpu_init(void)
 	 */
 	quark_setup_bars();
 
+	/*
+	 * Initialize PCIe controller
+	 *
+	 * Quark SoC holds the PCIe controller in reset following a power on.
+	 * U-Boot needs to release the PCIe controller from reset. The PCIe
+	 * controller (D23:F0/F1) will not be visible in PCI configuration
+	 * space and any access to its PCI configuration registers will cause
+	 * system hang while it is held in reset.
+	 */
+	quark_pcie_early_init();
+
 	/* Turn on legacy segments (A/B/E/F) decode to system RAM */
 	quark_enable_legacy_seg();
 
diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h
index 1ce56934d6..aad7fbe883 100644
--- a/arch/x86/include/asm/arch-quark/quark.h
+++ b/arch/x86/include/asm/arch-quark/quark.h
@@ -12,6 +12,7 @@
 #define MSG_PORT_HOST_BRIDGE	0x03
 #define MSG_PORT_RMU		0x04
 #define MSG_PORT_MEM_MGR	0x05
+#define MSG_PORT_PCIE_AFE	0x16
 #define MSG_PORT_SOC_UNIT	0x31
 
 /* Port 0x00: Memory Arbiter Message Port Registers */
@@ -48,6 +49,21 @@
 #define ESRAM_BLK_CTRL		0x82
 #define ESRAM_BLOCK_MODE	0x10000000
 
+/* Port 0x16: PCIe AFE Unit Port Registers */
+
+#define PCIE_RXPICTRL0_L0	0x2080
+#define PCIE_RXPICTRL0_L1	0x2180
+
+/* Port 0x31: SoC Unit Port Registers */
+
+/* PCIe Controller Config */
+#define PCIE_CFG		0x36
+#define PCIE_CTLR_PRI_RST	0x00010000
+#define PCIE_PHY_SB_RST		0x00020000
+#define PCIE_CTLR_SB_RST	0x00040000
+#define PCIE_PHY_LANE_RST	0x00090000
+#define PCIE_CTLR_MAIN_RST	0x00100000
+
 /* DRAM */
 #define DRAM_BASE		0x00000000
 #define DRAM_MAX_SIZE		0x80000000
@@ -124,6 +140,32 @@ static inline void qrk_pci_write_config_dword(pci_dev_t dev, int offset,
 	outl(value, PCI_REG_DATA);
 }
 
+/**
+ * board_assert_perst() - Assert the PERST# pin
+ *
+ * The CPU interface to the PERST# signal on Quark is platform dependent.
+ * Board-specific codes need supply this routine to assert PCIe slot reset.
+ *
+ * The tricky part in this routine is that any APIs that may trigger PCI
+ * enumeration process are strictly forbidden, as any access to PCIe root
+ * port's configuration registers will cause system hang while it is held
+ * in reset.
+ */
+void board_assert_perst(void);
+
+/**
+ * board_deassert_perst() - De-assert the PERST# pin
+ *
+ * The CPU interface to the PERST# signal on Quark is platform dependent.
+ * Board-specific codes need supply this routine to de-assert PCIe slot reset.
+ *
+ * The tricky part in this routine is that any APIs that may trigger PCI
+ * enumeration process are strictly forbidden, as any access to PCIe root
+ * port's configuration registers will cause system hang while it is held
+ * in reset.
+ */
+void board_deassert_perst(void);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _QUARK_H_ */
diff --git a/board/intel/galileo/galileo.c b/board/intel/galileo/galileo.c
index 746ab277cb..c1087acb69 100644
--- a/board/intel/galileo/galileo.c
+++ b/board/intel/galileo/galileo.c
@@ -5,12 +5,68 @@
  */
 
 #include <common.h>
+#include <asm/io.h>
+#include <asm/arch/device.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/quark.h>
 
 int board_early_init_f(void)
 {
 	return 0;
 }
 
+/*
+ * Intel Galileo gen2 board uses GPIO Resume Well bank pin0 as the PERST# pin.
+ *
+ * We cannot use any public GPIO APIs in <asm-generic/gpio.h> to control this
+ * pin, as these APIs will eventually call into gpio_ich6_ofdata_to_platdata()
+ * in the Intel ICH6 GPIO driver where it calls PCI configuration space access
+ * APIs which will trigger PCI enumeration process.
+ *
+ * Check <asm/arch-quark/quark.h> for more details.
+ */
+void board_assert_perst(void)
+{
+	u32 base, port, val;
+
+	/* retrieve the GPIO IO base */
+	qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, PCI_CFG_GPIOBASE, &base);
+	base = (base & 0xffff) & ~0x7f;
+
+	/* enable the pin */
+	port = base + 0x20;
+	val = inl(port);
+	val |= (1 << 0);
+	outl(val, port);
+
+	/* configure the pin as output */
+	port = base + 0x24;
+	val = inl(port);
+	val &= ~(1 << 0);
+	outl(val, port);
+
+	/* pull it down (assert) */
+	port = base + 0x28;
+	val = inl(port);
+	val &= ~(1 << 0);
+	outl(val, port);
+}
+
+void board_deassert_perst(void)
+{
+	u32 base, port, val;
+
+	/* retrieve the GPIO IO base */
+	qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, PCI_CFG_GPIOBASE, &base);
+	base = (base & 0xffff) & ~0x7f;
+
+	/* pull it up (de-assert) */
+	port = base + 0x28;
+	val = inl(port);
+	val |= (1 << 0);
+	outl(val, port);
+}
+
 void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio)
 {
 	return;