First of all, I advice you not to cast values explicitly. Instead use 'Value' property as in:
bl.Element("line_item").Value equals g.Element("product").Value
As an answer to your question, there are several ways. You can do this by making your subqueries having distinct values according to the join condition, or the result can be made distinct according to a field what you want. I would prefer the first way.
var q1 = (from bl in XElement.Load(@"doc1.xml").Elements("line_item_data").GroupBy(i1 =>
i1.Element("line_item").Value).Select(i1 => i1.First())
join g in XElement.Load(@"doc2.xml").Elements("productVersionDetails").GroupBy(i1 =>
i1.Element("product").Value).Select(i1 => i1.First())
on bl.Element("line_item").Value equals g.Element("product").Value
select new XElement("product_item",
new XElement("version_id", g.Element("version_id").Value),
new XElement("technology", bl.Element("technology").Value),
new XElement("product", g.Element("product").Value),
new XElement("version", g.Element("version").Value),
new XElement("status", g.Element("status").Value),
new XElement("type", g.Element("type").Value),
new XElement("owner_name", g.Element("owner_name").Value),
new XElement("description", bl.Element("description").Value),
new XElement("os", g.Element("os").Value)
)).ToList();
But it still depends on according to which field you want to make it distinct. Make your decision according to your aim. In the example, I have just chosen the first record of duplicates (duplicated in its xml, not the other file), but it still may not be aligned with your intention.