diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index d267a04..dcbc838 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -1556,3 +1556,10 @@ mode.
 > Default: `true`
 
 Permit use of the `xsave/xrstor` instructions.
+
+### nr_lpis (ARM)
+> `= <integer>`
+
+> Default: `8192`
+
+Number of LPIs supported by Xen.
diff --git a/xen/arch/arm/gic-hip04.c b/xen/arch/arm/gic-hip04.c
index a42cf24..9a4091b 100644
--- a/xen/arch/arm/gic-hip04.c
+++ b/xen/arch/arm/gic-hip04.c
@@ -301,6 +301,8 @@ static void __init hip04gic_dist_init(void)
 
     /* Only 1020 interrupts are supported */
     gicv2_info.nr_lines = min(1020U, nr_lines);
+    /* Number of IRQ ids supported */
+    gicv2_info.nr_irq_ids = gicv2_info.nr_lines;
 
     /* Turn on the distributor */
     writel_gicd(GICD_CTL_ENABLE, GICD_CTLR);
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 793dca7..915fd63 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -287,6 +287,8 @@ static void __init gicv2_dist_init(void)
 
     /* Only 1020 interrupts are supported */
     gicv2_info.nr_lines = min(1020U, nr_lines);
+    /* Number of IRQ ids supported */
+    gicv2_info.nr_irq_ids = nr_lines;
 
     /* Turn on the distributor */
     writel_gicd(GICD_CTL_ENABLE, GICD_CTLR);
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index a8082ab..9a7d99f 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -58,6 +58,33 @@ static struct gic_info gicv3_info;
 /* per-cpu re-distributor base */
 DEFINE_PER_CPU(struct rdist, rdist);
 
+/* Enable/Disable ITS support */
+static bool_t its_enable  = 0;
+
+static void __init parse_its_param(char *s)
+{
+    if ( !parse_bool(s) )
+        its_enable = 0;
+}
+
+/* 'msi' command line option to enable/disable ITS */
+custom_param("msi", parse_its_param);
+
+/*
+ * Number of LPIs supported by Xen.
+ *
+ * The LPI identifier starts from 8192. Given that the hardware is
+ * providing the number of identifier bits, supporting LPIs requires at
+ * least 14 bits. This will represent 16384 interrupt ID of which 8192
+ * LPIs. So the minimum of LPIs supported when the hardware supports LPIs
+ * is 8192.
+ */
+#define DEFAULT_NR_LPIS    8192
+static unsigned int nr_lpis;
+
+/* 'nr_lpis' command line option to specify number of LPIs supported by Xen. */
+integer_param("nr_lpis", nr_lpis);
+
 #define GICD                   (gicv3.map_dbase)
 #define GICD_RDIST_BASE        (this_cpu(rdist).rbase)
 #define GICD_RDIST_SGI_BASE    (GICD_RDIST_BASE + SZ_64K)
@@ -529,6 +556,11 @@ static void gicv3_set_irq_properties(struct irq_desc *desc,
     spin_unlock(&gicv3.lock);
 }
 
+static int gicv3_dist_supports_lpis(void)
+{
+    return readl_relaxed(GICD + GICD_TYPER) & GICD_TYPER_LPIS_SUPPORTED;
+}
+
 static void __init gicv3_dist_init(void)
 {
     uint32_t type;
@@ -578,6 +610,23 @@ static void __init gicv3_dist_init(void)
 
     /* Only 1020 interrupts are supported */
     gicv3_info.nr_lines = min(1020U, nr_lines);
+
+    /*
+     * Number of IRQ ids supported.
+     * Here we override HW supported number of LPIs and
+     * limit to to LPIs specified in nr_lpis.
+     */
+    if ( its_enable && gicv3_dist_supports_lpis() )
+    {
+        /* Minimum number of lpi supported is 8192 */
+        if ( nr_lpis < DEFAULT_NR_LPIS )
+            nr_lpis = DEFAULT_NR_LPIS;
+
+        gicv3_info.nr_irq_ids = nr_lpis + FIRST_GIC_LPI;
+    }
+    else
+        gicv3_info.nr_irq_ids = gicv3_info.nr_lines;
+
 }
 
 static int gicv3_enable_redist(void)
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 4b46a71..0c43a5b 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -62,6 +62,16 @@ enum gic_version gic_hw_version(void)
    return gic_hw_ops->info->hw_version;
 }
 
+unsigned int gic_nr_irq_ids(void)
+{
+    return gic_hw_ops->info->nr_irq_ids;
+}
+
+bool_t gic_is_lpi(unsigned int irq)
+{
+    return (irq >= FIRST_GIC_LPI && irq < gic_nr_irq_ids());
+}
+
 unsigned int gic_number_lines(void)
 {
     return gic_hw_ops->info->nr_lines;
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 6189ac9..c6e7a8d 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -20,6 +20,7 @@
 
 #define NR_GIC_LOCAL_IRQS  NR_LOCAL_IRQS
 #define NR_GIC_SGI         16
+#define FIRST_GIC_LPI      8192
 #define MAX_RDIST_COUNT    4
 
 #define GICD_CTLR       (0x000)
@@ -304,6 +305,8 @@ struct gic_info {
     unsigned int maintenance_irq;
     /* Pointer to the device tree node representing the interrupt controller */
     const struct dt_device_node *node;
+    /* Number of IRQ IDs supported */
+    uint32_t nr_irq_ids;
 };
 
 struct gic_hw_operations {
@@ -365,6 +368,8 @@ void register_gic_ops(const struct gic_hw_operations *ops);
 int gic_make_hwdom_dt_node(const struct domain *d,
                            const struct dt_device_node *gic,
                            void *fdt);
+unsigned int gic_nr_irq_ids(void);
+bool_t gic_is_lpi(unsigned int irq);
 
 #endif /* __ASSEMBLY__ */
 #endif
