diff --git a/configure.ac b/configure.ac
index c13e77d3..f1a2161d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -196,6 +196,23 @@ required at compile time), but you should be sure to add a runtime
 dependency on it.])
 fi
 
+dnl **************
+dnl *** brotli ***
+dnl **************
+AC_MSG_CHECKING(whether to enable Brotli decoding support)
+AC_ARG_WITH(brotli,
+		AS_HELP_STRING([--with-brotli], [Build with Brotli support [default=no]]))
+AC_MSG_RESULT($with_brotli)
+
+AM_CONDITIONAL(BUILD_LIBSOUP_BROTLI, test $with_brotli = yes)
+
+if test "$with_brotli" = yes; then
+	PKG_CHECK_MODULES(BROTLI, libbrotlidec)
+	AC_SUBST(BROTLI_CFLAGS)
+	AC_SUBST(BROTLI_LIBS)
+	AC_DEFINE(LIBSOUP_HAVE_BROTLI, 1, [Defined if Brotli support is enabled])
+fi
+
 dnl ******************************
 dnl *** Stuff for regression tests
 dnl ******************************
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index 4232be66..ae089e76 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -26,6 +26,10 @@ AM_CPPFLAGS = 				\
 	$(CODE_COVERAGE_CFLAGS)		\
 	$(KRB5_CFLAGS)
 
+if BUILD_LIBSOUP_BROTLI
+AM_CPPFLAGS += $(BROTLI_CFLAGS)
+endif
+
 libsoupincludedir = $(includedir)/libsoup-2.4/libsoup
 
 soup_headers =			\
@@ -105,6 +109,10 @@ libsoup_2_4_la_LIBADD =			\
 	$(SQLITE_LIBS)			\
 	$(KRB5_LIBS)
 
+if BUILD_LIBSOUP_BROTLI
+libsoup_2_4_la_LIBADD += $(BROTLI_LIBS)
+endif
+
 libsoup_2_4_la_SOURCES =		\
 	gconstructor.h			\
 	soup-address.c			\
@@ -209,6 +217,12 @@ libsoup_2_4_la_SOURCES =		\
 	soup-xmlrpc.c			\
 	soup-xmlrpc-old.c
 
+if BUILD_LIBSOUP_BROTLI
+libsoup_2_4_la_SOURCES +=		\
+	soup-brotli-decompressor.c	\
+	soup-brotli-decompressor.h
+endif
+
 # TLD rules
 EXTRA_DIST += tld-parser.py
 
diff --git a/libsoup/soup-brotli-decompressor.c b/libsoup/soup-brotli-decompressor.c
new file mode 100644
index 00000000..48fe1a4b
--- /dev/null
+++ b/libsoup/soup-brotli-decompressor.c
@@ -0,0 +1,172 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "soup-brotli-decompressor.h"
+
+#include <brotli/decode.h>
+#include <gio/gio.h>
+
+typedef struct {
+	GObjectClass parent_class;
+
+} SoupBrotliDecompressorClass;
+
+struct _SoupBrotliDecompressor
+{
+	GObject parent_instance;
+
+	BrotliDecoderState* brotli_decoder;
+};
+
+#define G_TYPE_SOUP_BROTLI_DECOMPRESSOR (soup_brotli_decompressor_get_type ())
+#define SOUP_BROTLI_DECOMPRESSOR(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOUP_BROTLI_DECOMPRESSOR, SoupBrotliDecompressor))
+
+static void soup_brotli_decompressor_iface_init (GConverterIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (SoupBrotliDecompressor, soup_brotli_decompressor, G_TYPE_OBJECT,
+	G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, soup_brotli_decompressor_iface_init))
+
+SoupBrotliDecompressor *
+soup_brotli_decompressor_new (void)
+{
+	SoupBrotliDecompressor *decompressor;
+
+	decompressor = g_object_new (G_TYPE_SOUP_BROTLI_DECOMPRESSOR, NULL);
+
+	return decompressor;
+}
+
+static void
+soup_brotli_decompressor_init (SoupBrotliDecompressor *decompressor)
+{
+}
+
+static void*
+soup_brotli_decompressor_alloc (void* opaque, size_t size)
+{
+    return g_malloc (size);
+}
+
+static void
+soup_brotli_decompressor_free (void* opaque, void* address)
+{
+    g_free (address);
+}
+
+static void
+soup_brotli_decompressor_constructed (GObject *object)
+{
+	SoupBrotliDecompressor *decompressor;
+
+    decompressor = SOUP_BROTLI_DECOMPRESSOR (object);
+
+    decompressor->brotli_decoder = BrotliDecoderCreateInstance (
+				soup_brotli_decompressor_alloc,
+				soup_brotli_decompressor_free,
+				NULL);
+}
+
+static void
+soup_brotli_decompressor_finalize (GObject *object)
+{
+	SoupBrotliDecompressor *decompressor;
+
+    decompressor = SOUP_BROTLI_DECOMPRESSOR (object);
+
+    BrotliDecoderDestroyInstance (decompressor->brotli_decoder);
+}
+
+static void
+soup_brotli_decompressor_class_init (SoupBrotliDecompressorClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	gobject_class->constructed = soup_brotli_decompressor_constructed;
+    gobject_class->finalize = soup_brotli_decompressor_finalize;
+}
+
+static GConverterResult
+soup_brotli_decompressor_convert (GConverter *converter,
+									const void *inbuf,
+									gsize inbuf_size,
+									void *outbuf,
+									gsize outbuf_size,
+									GConverterFlags flags,
+									gsize *bytes_read,
+									gsize *bytes_written,
+									GError **error)
+{
+	SoupBrotliDecompressor *decompressor;
+	BrotliDecoderResult res;
+	gsize available_in, available_out;
+    const uint8_t *next_in;
+	uint8_t *next_out;
+
+    decompressor = SOUP_BROTLI_DECOMPRESSOR (converter);
+
+	if (decompressor->brotli_decoder == NULL)
+		return G_CONVERTER_ERROR;
+
+	available_in = inbuf_size;
+	next_in = inbuf;
+	available_out = outbuf_size;
+	next_out = outbuf;
+
+	res = BrotliDecoderDecompressStream (decompressor->brotli_decoder,
+					&available_in, &next_in,
+					&available_out, &next_out,
+					NULL);
+
+	if (res == BROTLI_DECODER_RESULT_ERROR) {
+		g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "");
+		return G_CONVERTER_ERROR;
+	}
+
+	if (available_in > inbuf_size || available_out > outbuf_size)
+		return G_CONVERTER_ERROR;
+
+	*bytes_read = inbuf_size - available_in;
+	*bytes_written = outbuf_size - available_out;
+
+	if (res == BROTLI_DECODER_RESULT_SUCCESS)
+        return G_CONVERTER_FINISHED;
+
+	if (*bytes_read > 0 || *bytes_written > 0)
+		return G_CONVERTER_CONVERTED;
+
+	if (res == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
+        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, "");
+		return G_CONVERTER_ERROR;
+	}
+
+	if (res == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
+		g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, "");
+        return G_CONVERTER_ERROR;
+	}
+
+	return G_CONVERTER_ERROR;
+}
+
+static void
+soup_brotli_decompressor_reset (GConverter *converter)
+{
+	SoupBrotliDecompressor *decompressor;
+
+    decompressor = SOUP_BROTLI_DECOMPRESSOR (converter);
+
+    if (decompressor->brotli_decoder)
+        BrotliDecoderDestroyInstance (decompressor->brotli_decoder);
+
+    decompressor->brotli_decoder = BrotliDecoderCreateInstance (
+				soup_brotli_decompressor_alloc,
+				soup_brotli_decompressor_free,
+				NULL);
+}
+
+static void
+soup_brotli_decompressor_iface_init (GConverterIface *iface)
+{
+	iface->convert = soup_brotli_decompressor_convert;
+	iface->reset = soup_brotli_decompressor_reset;
+}
diff --git a/libsoup/soup-brotli-decompressor.h b/libsoup/soup-brotli-decompressor.h
new file mode 100644
index 00000000..e210e195
--- /dev/null
+++ b/libsoup/soup-brotli-decompressor.h
@@ -0,0 +1,12 @@
+#ifndef SOUP_BROTLI_DECOMPRESSOR_H
+#define SOUP_BROTLI_DECOMPRESSOR_H 1
+
+#include <gio/gio.h>
+
+typedef struct _SoupBrotliDecompressor SoupBrotliDecompressor;
+
+GType soup_brotli_decompressor_get_type (void) G_GNUC_CONST;
+
+SoupBrotliDecompressor *soup_brotli_decompressor_new (void);
+
+#endif /* SOUP_BROTLI_DECOMPRESSOR_H */
diff --git a/libsoup/soup-content-decoder.c b/libsoup/soup-content-decoder.c
index 080904aa..6218e50f 100644
--- a/libsoup/soup-content-decoder.c
+++ b/libsoup/soup-content-decoder.c
@@ -9,6 +9,7 @@
 #include <config.h>
 #endif
 
+#include "soup-brotli-decompressor.h"
 #include "soup-content-decoder.h"
 #include "soup-converter-wrapper.h"
 #include "soup.h"
@@ -169,7 +170,11 @@ soup_content_decoder_content_processor_init (SoupContentProcessorInterface *proc
 }
 
 /* This is constant for now */
+#ifdef LIBSOUP_HAVE_BROTLI
+#define ACCEPT_ENCODING_HEADER "gzip, deflate, br"
+#else
 #define ACCEPT_ENCODING_HEADER "gzip, deflate"
+#endif
 
 static GConverter *
 gzip_decoder_creator (void)
@@ -183,6 +188,14 @@ zlib_decoder_creator (void)
 	return (GConverter *)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB);
 }
 
+#ifdef LIBSOUP_HAVE_BROTLI
+static GConverter *
+brotli_decoder_creator (void)
+{
+    return (GConverter *)soup_brotli_decompressor_new ();
+}
+#endif
+
 static void
 soup_content_decoder_init (SoupContentDecoder *decoder)
 {
@@ -196,6 +209,11 @@ soup_content_decoder_init (SoupContentDecoder *decoder)
 			     gzip_decoder_creator);
 	g_hash_table_insert (decoder->priv->decoders, "deflate",
 			     zlib_decoder_creator);
+
+#ifdef LIBSOUP_HAVE_BROTLI
+	g_hash_table_insert (decoder->priv->decoders, "br",
+			     brotli_decoder_creator);
+#endif
 }
 
 static void
